빈 Pandas DataFrame을 만든 다음 채우시겠습니까?
나는 pandas DataFrame 문서에서 시작합니다 : http://pandas.pydata.org/pandas-docs/stable/dsintro.html
시계열 종류의 계산 값으로 DataFrame을 반복적으로 채우고 싶습니다. 따라서 기본적으로 열 A, B 및 타임 스탬프 행, 모두 0 또는 모든 NaN으로 DataFrame을 초기화하고 싶습니다.
그런 다음 초기 값을 추가 하고이 데이터를 검토하여 이전 행에서 새 행을 계산합니다 row[A][t] = row[A][t-1]+1
.
나는 현재 아래와 같이 코드를 사용하고 있지만, 그것이 추악하다고 느끼며 DataFrame으로 직접 또는 일반적으로 더 나은 방법 으로이 작업을 수행 할 수있는 방법이 있어야합니다. 참고 : Python 2.7을 사용하고 있습니다.
import datetime as dt
import pandas as pd
import scipy as s
if __name__ == '__main__':
base = dt.datetime.today().date()
dates = [ base - dt.timedelta(days=x) for x in range(0,10) ]
dates.sort()
valdict = {}
symbols = ['A','B', 'C']
for symb in symbols:
valdict[symb] = pd.Series( s.zeros( len(dates)), dates )
for thedate in dates:
if thedate > dates[0]:
for symb in valdict:
valdict[symb][thedate] = 1+valdict[symb][thedate - dt.timedelta(days=1)]
print valdict
다음은 몇 가지 제안입니다.
date_range
색인에 사용하십시오 .
import datetime
import pandas as pd
import numpy as np
todays_date = datetime.datetime.now().date()
index = pd.date_range(todays_date-datetime.timedelta(10), periods=10, freq='D')
columns = ['A','B', 'C']
참고 : NaN
간단히 다음 과 같이 작성하여 빈 DataFrame ( s 포함)을 만들 수 있습니다 .
df_ = pd.DataFrame(index=index, columns=columns)
df_ = df_.fillna(0) # with 0s rather than NaNs
데이터에 대해 이러한 유형의 계산을 수행하려면 numpy 배열을 사용하십시오.
data = np.array([np.arange(10)]*3).T
따라서 DataFrame을 만들 수 있습니다.
In [10]: df = pd.DataFrame(data, index=index, columns=columns)
In [11]: df
Out[11]:
A B C
2012-11-29 0 0 0
2012-11-30 1 1 1
2012-12-01 2 2 2
2012-12-02 3 3 3
2012-12-03 4 4 4
2012-12-04 5 5 5
2012-12-05 6 6 6
2012-12-06 7 7 7
2012-12-07 8 8 8
2012-12-08 9 9 9
빈 데이터 프레임을 만들고 나중에 들어오는 데이터 프레임으로 채우려면 다음을 시도하십시오.
이 예제에서는이 팬더 문서 를 사용하여 새 데이터 프레임을 만든 다음 append 를 사용 하여 oldDF의 데이터로 newDF에 씁니다.
이것 좀 봐
newDF = pd.DataFrame() #creates a new dataframe that's empty
newDF = newDF.append(oldDF, ignore_index = True) # ignoring index is optional
# try printing some data from newDF
print newDF.head() #again optional
- 하나 이상의 oldDF 에서이 newDF에 새로운 데이터를 계속 추가 해야하는 경우 for 루프를 사용하여 pandas 를 반복합니다 .DataFrame.append ()
처음부터 열 이름을 사용하려면 다음 방법을 사용하십시오.
import pandas as pd
col_names = ['A', 'B', 'C']
my_df = pd.DataFrame(columns = col_names)
my_df
데이터 프레임에 레코드를 추가하려면 다음을 사용하는 것이 좋습니다.
my_df.loc[len(my_df)] = [2, 4, 5]
사전을 전달할 수도 있습니다.
my_dic = {'A':2, 'B':4, 'C':5}
my_df.loc[len(my_df)] = my_dic
그러나 my_df에 다른 데이터 프레임을 추가하려면 다음과 같이하십시오.
col_names = ['A', 'B', 'C']
my_df2 = pd.DataFrame(columns = col_names)
my_df = my_df.append(my_df2)
루프 내부에 행을 추가하는 경우 성능 문제를 고려
하십시오. 처음 1000 개 레코드의 경우 "my_df.loc"성능이 더 좋지만 루프의 레코드 수를 늘림으로써 점차 느려집니다.
큰 루프 내에서 씬을 만들 계획이라면 (예 : 10M 레코드) :
이 두 가지를 혼합하여 사용하는 것이 좋습니다. 크기가 약 1000이 될 때까지 데이터 프레임을 iloc으로 채운 다음 원래 데이터 프레임에 추가하고 임시 데이터 프레임을 비 웁니다. 이렇게하면 성능이 약 10 배 향상됩니다.
DataFrame을 만드는 올바른 방법
여기에있는 대부분의 대답은 빈 DataFrame을 만들고 채우는 방법을 알려주지 만 나쁜 일이라고 말하는 사람은 없습니다.
여기 내 충고가 있습니다 : 작업해야 할 모든 데이터가 확보 될 때까지 기다리십시오. 목록을 사용하여 데이터를 수집 한 다음 준비가되면 DataFrame을 초기화하십시오.
data = []
for a, b, c in some_function_that_yields_data():
data.append([a, b, c])
df = pd.DataFrame(data, columns=['A', 'B', 'C'])
빈 DataFrame (또는 NaN 중 하나)을 만들고 반복해서 추가하는 것보다 목록에 추가하고 한 번에 DataFrame을 만드는 것이 항상 저렴 합니다. 또한 목록은 메모리를 덜 차지하고 , 추가 및 제거 (필요한 경우)에 사용할 수있는 훨씬 가벼운 데이터 구조 입니다.
이 방법의 다른 장점은 모든 방법에 할당하지 않고 dtypes
자동으로 유추됩니다object
.
마지막 장점은 데이터에 대해 a RangeIndex
가 자동으로 생성 되므로 걱정할 필요가 없다는 것입니다 (아래 의 가난한 방법 append
과 loc
방법을 살펴보면 인덱스를 적절하게 처리 해야하는 요소가 모두 표시됩니다).
하지 말아야 할 것
append
또는 concat
루프 내부
초보자에게서 본 가장 큰 실수는 다음과 같습니다.
df = pd.DataFrame(columns=['A', 'B', 'C'])
for a, b, c in some_function_that_yields_data():
df = df.append({'A': i, 'B': b, 'C': c}, ignore_index=True) # yuck
# or similarly,
# df = pd.concat([df, pd.Series({'A': i, 'B': b, 'C': c})], ignore_index=True)
모든 append
또는 concat
작업 마다 메모리가 다시 할당됩니다 . 이것을 루프와 결합하면 2 차 복잡도 연산이 됩니다. 로부터 df.append
문서 페이지 :
반복적으로 DataFrame에 행을 추가하면 단일 연결보다 계산 집약적 일 수 있습니다. 더 나은 해결책은 해당 행을 목록에 추가 한 다음 목록을 원래 DataFrame과 한 번에 연결하는 것입니다.
또 다른 실수 df.append
는 사용자 가 추가 기능 을 잊어 버리는 경향이 있다는 점 입니다. 결과는 내부 기능 이 아니므로 결과를 다시 할당해야합니다. 또한 dtype에 대해 걱정해야합니다.
df = pd.DataFrame(columns=['A', 'B', 'C'])
df = df.append({'A': 1, 'B': 12.3, 'C': 'xyz'}, ignore_index=True)
df.dtypes
A object # yuck!
B float64
C object
dtype: object
팬더는 해당 열에 대한 작업을 벡터화 할 수 없으므로 객체 열을 다루는 것은 결코 좋은 일이 아닙니다. 수정하려면 다음을 수행해야합니다.
df.infer_objects().dtypes
A int64
B float64
C object
dtype: object
loc
루프 내부
또한 loc
비어있는 DataFrame에 추가하는 데 사용되는 것을 보았습니다 .
df = pd.DataFrame(columns=['A', 'B', 'C'])
for a, b, c in some_function_that_yields_data():
df.loc[len(df)] = [a, b, c]
이전과 같이 매번 필요한 메모리 양을 미리 할당하지 않았으므로 새 행을 만들 때마다 메모리가 다시 증가합니다 . 이만큼 나쁘고 append
더 추악합니다.
NaN의 빈 데이터 프레임
그리고 NaN의 DataFrame과 이와 관련된 모든 경고가 생성됩니다.
df = pd.DataFrame(columns=['A', 'B', 'C'], index=range(5))
df
A B C
0 NaN NaN NaN
1 NaN NaN NaN
2 NaN NaN NaN
3 NaN NaN NaN
4 NaN NaN NaN
다른 것과 같이 객체 열의 DataFrame을 만듭니다.
df.dtypes
A object # you DON'T want this
B object
C object
dtype: object
Appending은 여전히 위의 방법으로 모든 문제가 있습니다.
for i, (a, b, c) in enumerate(some_function_that_yields_data()):
df.iloc[i] = [a, b, c]
증명은 푸딩에 있습니다.
이러한 방법의 타이밍은 메모리와 유틸리티 측면에서 얼마나 다른지 확인할 수있는 가장 빠른 방법입니다.
19 행의 데이터 프레임을 가정
index=range(0,19)
index
columns=['A']
test = pd.DataFrame(index=index, columns=columns)
A 열을 일정하게 유지
test['A']=10
열 b를 루프가 제공하는 변수로 유지
for x in range(0,19):
test.loc[[x], 'b'] = pd.Series([x], index = [x])
첫 x pd.Series([x], index = [x])
를 임의의 값으로 바꿀 수 있습니다
참고 URL : https://stackoverflow.com/questions/13784192/creating-an-empty-pandas-dataframe-then-filling-it
'development' 카테고리의 다른 글
Microsoft .NET 4.0 전체 프레임 워크와 클라이언트 프로파일의 차이점 (0) | 2020.02.29 |
---|---|
EXE를 출력하기 위해 .NET Core 콘솔 응용 프로그램을 빌드 하시겠습니까? (0) | 2020.02.29 |
AngularJS 컨트롤러간에 데이터 공유 (0) | 2020.02.29 |
바이트 + 바이트 = int… 왜? (0) | 2020.02.29 |
PreferenceActivity에서 "addPreferencesFromResource"대신 무엇을 사용해야합니까? (0) | 2020.02.29 |