데이터 프레임을 여러 데이터 프레임으로 분할
저는 매우 큰 데이터 프레임(약 100만 행)과 실험(60명의 응답자)의 데이터를 가지고 있습니다.
데이터 프레임을 60개의 데이터 프레임(참가자별 데이터 프레임)으로 나누고 싶습니다.
데이터 프레임에서,data, 라는 변수가 있습니다.'name', 각 참가자의 고유 코드입니다.
다음을 시도해 보았지만 아무 일도 일어나지 않습니다(또는 실행이 1시간 이내에 중지되지 않음).내가 하려는 것은 그들을 분열시키는 것입니다.data작은 데이터 프레임에 추가하고 목록에 추가합니다(datalist):
import pandas as pd
def splitframe(data, name='name'):
n = data[name][0]
df = pd.DataFrame(columns=data.columns)
datalist = []
for i in range(len(data)):
if data[name][i] == n:
df = df.append(data.iloc[i])
else:
datalist.append(df)
df = pd.DataFrame(columns=data.columns)
n = data[name][i]
df = df.append(data.iloc[i])
return datalist
오류 메시지가 표시되지 않습니다. 스크립트가 영원히 실행되는 것 같습니다!
현명한 방법이 있습니까?
왜 그냥 데이터 프레임을 잘라내서 하지 않는지 물어봐도 될까요?뭐 이런 거.
#create some data with Names column
data = pd.DataFrame({'Names': ['Joe', 'John', 'Jasper', 'Jez'] *4, 'Ob1' : np.random.rand(16), 'Ob2' : np.random.rand(16)})
#create unique list of names
UniqueNames = data.Names.unique()
#create a data frame dictionary to store your data frames
DataFrameDict = {elem : pd.DataFrame() for elem in UniqueNames}
for key in DataFrameDict.keys():
DataFrameDict[key] = data[:][data.Names == key]
예, 데이터 프레임에 대한 사전이 필요한 것처럼 있습니다.접속할 필요가 있습니까?그냥들어가기
DataFrameDict['Joe']
첫째, 새로운 엔트리를 위한 공간이 부족할 때 주기적으로 리스트를 늘려야 하기 때문에 행 단위로 리스트에 첨부하는 것이 더 느리기 때문에 당신의 접근 방식은 비효율적입니다. 이 점에서 리스트를 미리 크기를 정하고 한 번 할당하기 때문에 리스트를 이해하는 것이 더 낫습니다.
하지만 이미 데이터 프레임을 가지고 있기 때문에 근본적으로 귀하의 접근 방식은 약간 낭비적이라고 생각합니다. 그런데 왜 이러한 사용자 각각에 대해 새 프레임을 만들까요?
열별로 데이터 프레임을 정렬하겠습니다.'name', 인덱스를 이 값으로 설정하고 필요한 경우 열을 떨어뜨리지 마십시오.
그런 다음 모든 고유한 항목의 목록을 생성한 다음 이러한 항목을 사용하여 조회를 수행할 수 있으며, 데이터만 쿼리하는 경우에는 선택 기준을 사용하여 값비싼 데이터 복사본을 발생시키지 않고 데이터 프레임에 대한 보기를 반환할 수 있습니다.
사용 및 :
# sort the dataframe
df.sort_values(by='name', axis=1, inplace=True)
# set the index to be this and don't drop
df.set_index(keys=['name'], drop=False,inplace=True)
# get a list of names
names=df['name'].unique().tolist()
# now we can perform a lookup on a 'view' of the dataframe
joe = df.loc[df.name=='joe']
# now you can query all 'joes'
개체를 다음으로 변환할 수 있습니다.tuples그다음에dict:
df = pd.DataFrame({'Name':list('aabbef'),
'A':[4,5,4,5,5,4],
'B':[7,8,9,4,2,3],
'C':[1,3,5,7,1,0]}, columns = ['Name','A','B','C'])
print (df)
Name A B C
0 a 4 7 1
1 a 5 8 3
2 b 4 9 5
3 b 5 4 7
4 e 5 2 1
5 f 4 3 0
d = dict(tuple(df.groupby('Name')))
print (d)
{'b': Name A B C
2 b 4 9 5
3 b 5 4 7, 'e': Name A B C
4 e 5 2 1, 'a': Name A B C
0 a 4 7 1
1 a 5 8 3, 'f': Name A B C
5 f 4 3 0}
print (d['a'])
Name A B C
0 a 4 7 1
1 a 5 8 3
권장되지 않지만 그룹별로 데이터 프레임을 생성할 수 있습니다.
for i, g in df.groupby('Name'):
globals()['df_' + str(i)] = g
print (df_a)
Name A B C
0 a 4 7 1
1 a 5 8 3
쉬운:
[v for k, v in df.groupby('name')]
Groupby는 다음을 지원합니다.
grouped = data.groupby(['name'])
그러면 참가자별 데이터 프레임처럼 각 그룹과 함께 작업할 수 있습니다.그리고 DataFrameGroupBy(적용, 변환, 집계, 머리, 처음, 마지막)와 같은 객체 방식으로 DataFrame 객체를 반환합니다.
또는 목록을 만들 수 있습니다.grouped인덱스별로 모든 DataFrame을 가져옵니다.
l_grouped = list(grouped)
l_grouped[0][1]- 이름이 있는 첫 번째 그룹의 DataFrame입니다.
Gusev Slava의 답변 외에도 groupby의 그룹을 사용할 수 있습니다.
{key: df.loc[value] for key, value in df.groupby("name").groups.items()}
이렇게 하면 그룹화된 키가 있는 해당 파티션을 가리키는 사전이 생성됩니다.키가 유지되고 목록 색인에서 사라지지 않는 것이 장점입니다.
- OP의 방법은 효과는 있지만 효율적이지는 않습니다.데이터셋이 길었기 때문에 영원히 실행되는 것처럼 보였을 수도 있습니다.
- 사용처
'method'열을 만들고 a를 만듭니다.dictDataFrames독특한'method'값을 키로 지정합니다..groupby답례품 agroupbyobject, 그룹에 대한 정보를 포함하며, 여기서g는 의 고유 값입니다.'method'그룹별로, 그리고d. ㅇDataFrame그 그룹을 위해서.
-
value각각의key인에df_dict, 가 될 것입니다.DataFrame, 일반적인 방법으로 접근할 수 있고,df_dict['key']. - 원래 질문은.
listDataFrames, 그것은 a로 할 수 있습니다.df_list = [d for _, d in df.groupby('method')]
import pandas as pd
import seaborn as sns # for test dataset
# load data for example
df = sns.load_dataset('planets')
# display(df.head())
method number orbital_period mass distance year
0 Radial Velocity 1 269.300 7.10 77.40 2006
1 Radial Velocity 1 874.774 2.21 56.95 2008
2 Radial Velocity 1 763.000 2.60 19.84 2011
3 Radial Velocity 1 326.030 19.40 110.62 2007
4 Radial Velocity 1 516.220 10.50 119.47 2009
# Using a dict-comprehension, the unique 'method' value will be the key
df_dict = {g: d for g, d in df.groupby('method')}
print(df_dict.keys())
[out]:
dict_keys(['Astrometry', 'Eclipse Timing Variations', 'Imaging', 'Microlensing', 'Orbital Brightness Modulation', 'Pulsar Timing', 'Pulsation Timing Variations', 'Radial Velocity', 'Transit', 'Transit Timing Variations'])
# or a specific name for the key, using enumerate (e.g. df1, df2, etc.)
df_dict = {f'df{i}': d for i, (g, d) in enumerate(df.groupby('method'))}
print(df_dict.keys())
[out]:
dict_keys(['df0', 'df1', 'df2', 'df3', 'df4', 'df5', 'df6', 'df7', 'df8', 'df9'])
df_dict['df1].head(3)아니면df_dict['Astrometry'].head(3)- 이 그룹에는 2명밖에 없습니다.
method number orbital_period mass distance year
113 Astrometry 1 246.36 NaN 20.77 2013
537 Astrometry 1 1016.00 NaN 14.98 2010
df_dict['df2].head(3)아니면df_dict['Eclipse Timing Variations'].head(3)
method number orbital_period mass distance year
32 Eclipse Timing Variations 1 10220.0 6.05 NaN 2009
37 Eclipse Timing Variations 2 5767.0 NaN 130.72 2008
38 Eclipse Timing Variations 2 3321.0 NaN 130.72 2008
df_dict['df3].head(3)아니면df_dict['Imaging'].head(3)
method number orbital_period mass distance year
29 Imaging 1 NaN NaN 45.52 2005
30 Imaging 1 NaN NaN 165.00 2007
31 Imaging 1 NaN NaN 140.00 2004
또는
- 이 방법은 별도의 작업을 생성하는 수동 방법입니다.
DataFrames팬더 사용하기: 부울 인덱싱 - 이는 수용된 답변과 유사하지만,
.loc필요하지 않습니다. - 이 방법은 몇 개의 추가 데이터를 생성하는 데 허용되는 방법입니다.
DataFrames. - 여러 개체를 만드는 파이톤적인 방법은 개체를 용기에 넣는 것입니다.
dict,list,generator(),.
df1 = df[df.method == 'Astrometry']
df2 = df[df.method == 'Eclipse Timing Variations']
In [28]: df = DataFrame(np.random.randn(1000000,10))
In [29]: df
Out[29]:
<class 'pandas.core.frame.DataFrame'>
Int64Index: 1000000 entries, 0 to 999999
Data columns (total 10 columns):
0 1000000 non-null values
1 1000000 non-null values
2 1000000 non-null values
3 1000000 non-null values
4 1000000 non-null values
5 1000000 non-null values
6 1000000 non-null values
7 1000000 non-null values
8 1000000 non-null values
9 1000000 non-null values
dtypes: float64(10)
In [30]: frames = [ df.iloc[i*60:min((i+1)*60,len(df))] for i in xrange(int(len(df)/60.) + 1) ]
In [31]: %timeit [ df.iloc[i*60:min((i+1)*60,len(df))] for i in xrange(int(len(df)/60.) + 1) ]
1 loops, best of 3: 849 ms per loop
In [32]: len(frames)
Out[32]: 16667
여기 그룹이 있습니다. (합산이 아닌 임의 적용도 가능합니다.
In [9]: g = df.groupby(lambda x: x/60)
In [8]: g.sum()
Out[8]:
<class 'pandas.core.frame.DataFrame'>
Int64Index: 16667 entries, 0 to 16666
Data columns (total 10 columns):
0 16667 non-null values
1 16667 non-null values
2 16667 non-null values
3 16667 non-null values
4 16667 non-null values
5 16667 non-null values
6 16667 non-null values
7 16667 non-null values
8 16667 non-null values
9 16667 non-null values
dtypes: float64(10)
Sum은 cytonized 되어있고 그래서 이것이 매우 빠른 이유입니다.
In [10]: %timeit g.sum()
10 loops, best of 3: 27.5 ms per loop
In [11]: %timeit df.groupby(lambda x: x/60)
1 loops, best of 3: 231 ms per loop
리스트 이해에 기반한 방법 및groupby- 모든 분할 데이터 프레임을 목록 변수에 저장하고 인덱스를 사용하여 액세스할 수 있습니다.
예
ans = [pd.DataFrame(y) for x, y in DF.groupby('column_name', as_index=False)]
ans[0]
ans[0].column_name
데이터에 대한 레이블이 이미 있는 경우 명령별 그룹을 사용할 수 있습니다.
out_list = [group[1] for group in in_series.groupby(label_series.values)]
자세한 예는 다음과 같습니다.
예를 들어 일부 레이블을 사용하여 pd 시리즈를 청크 목록으로 분할하려고 합니다.in_series다음과 같습니다.
2019-07-01 08:00:00 -0.10
2019-07-01 08:02:00 1.16
2019-07-01 08:04:00 0.69
2019-07-01 08:06:00 -0.81
2019-07-01 08:08:00 -0.64
Length: 5, dtype: float64
그리고 그에 상응하는label_series다음과 같습니다.
2019-07-01 08:00:00 1
2019-07-01 08:02:00 1
2019-07-01 08:04:00 2
2019-07-01 08:06:00 2
2019-07-01 08:08:00 2
Length: 5, dtype: float64
달려.
out_list = [group[1] for group in in_series.groupby(label_series.values)]
돌아오는.out_list a list둘중에pd.Series:
[2019-07-01 08:00:00 -0.10
2019-07-01 08:02:00 1.16
Length: 2, dtype: float64,
2019-07-01 08:04:00 0.69
2019-07-01 08:06:00 -0.81
2019-07-01 08:08:00 -0.64
Length: 3, dtype: float64]
일부 매개 변수를 사용할 수 있습니다.in_series그 자체가 시리즈를 그룹화합니다. 예를 들어,in_series.index.day
일부에게 도움이 될 수 있는 작은 기능이 있습니다(효율성은 완벽하지 않지만 콤팩트한 + 어느 정도 이해하기 쉽습니다).
def get_splited_df_dict(df: 'pd.DataFrame', split_column: 'str'):
"""
splits a pandas.DataFrame on split_column and returns it as a dict
"""
df_dict = {value: df[df[split_column] == value].drop(split_column, axis=1) for value in df[split_column].unique()}
return df_dict
주어진 열에서 각각의 고유 값을 선택하고 모든 엔트리를 별도의 DataFrame에 넣음으로써 DataFrame을 여러 DataFrame으로 변환합니다..drop(split_column, axis=1)는 DataFrame을 분할하는 데 사용된 열을 제거하기 위한 것입니다.제거는 필요하지 않지만, 수술 후 메모리 사용량을 줄이는 데 조금 도움이 될 수 있습니다.
의 결과get_splited_df_dict가dict, 즉, 다음과 같이 각 DataFrame에 액세스할 수 있습니다.
splitted = get_splited_df_dict(some_df, some_column)
# accessing the DataFrame with 'some_column_value'
splitted[some_column_value]
기존의 답변들은 모든 좋은 사례들을 포함하고 있으며, 그 방법을 꽤 잘 설명하고 있습니다.groupby객체는 키와 값이 있는 사전과 같습니다..groups. 그러나 기존 답변과 동일한 작업을 수행하는 더 많은 방법은 다음과 같습니다.
- 개체별로 그룹을 풀고 사전에 캐스팅하여 목록을 만듭니다.
dict([*df.groupby('Name')]) # same as dict(list(df.groupby('Name')))
- 튜플 + dict 만들기 (@jezrail의 답변과 동일):
dict((*df.groupby('Name'),))
- DataFrame만 원한다면 사전의 값(위에서 작성)을 얻을 수 있습니다.
[*dict([*df.groupby('Name')]).values()]
저도 비슷한 문제가 있었습니다.저는 10개의 다양한 매장과 50개의 다양한 품목에 대한 일일 판매 타임 시리즈를 가졌습니다.원래 데이터 프레임을 500개의 데이터 프레임(10개의 스토어*50개의 스토어)으로 나누어 머신 러닝 모델을 각각 적용해야 했고, 수작업으로는 할 수 없었습니다.
다음은 데이터 프레임의 헤드입니다.
하나는 데이터 프레임의 이름에 대한 목록이고 하나는 배열의 쌍 [item_number, store_number]에 대한 목록입니다.
list=[]
for i in range(1,len(items)*len(stores)+1):
global list
list.append('df'+str(i))
list_couple_s_i =[]
for item in items:
for store in stores:
global list_couple_s_i
list_couple_s_i.append([item,store])
그리고 두 개의 목록이 준비되면 이 목록을 순환시켜 원하는 데이터 프레임을 생성할 수 있습니다.
for name, it_st in zip(list,list_couple_s_i):
globals()[name] = df.where((df['item']==it_st[0]) &
(df['store']==(it_st[1])))
globals()[name].dropna(inplace=True)
이런 식으로 500개의 데이터 프레임을 만들었습니다.
이것이 도움이 되기를 바랍니다!
언급URL : https://stackoverflow.com/questions/19790790/splitting-dataframe-into-multiple-dataframes
'codememo' 카테고리의 다른 글
| AJAX 성공 후 모드 창을 닫으려면 어떻게 해야 합니까? (0) | 2023.10.30 |
|---|---|
| 튜플이 목록보다 메모리 공간을 적게 차지하는 이유는 무엇입니까? (0) | 2023.10.30 |
| Angular JS - 단추 클릭 시 지시문에서 템플릿 html 로드 (0) | 2023.10.30 |
| JavaScript에서 MariaDB로 데이터 전송 시 밀리초의 정확도 유지 (0) | 2023.10.30 |
| html 엔티티를 해독하는 mysql 함수가 있습니까? (0) | 2023.10.30 |
