非常に大きなデータフレーム(約100万行)に実験データ(60人の回答者)があります。データフレームを60個のデータフレーム(各参加者のデータフレーム)に分割したいと思います。
データフレーム(=データと呼ばれる)には、各参加者の一意のコードである「名前」という変数があります。
次のことを試しましたが、何も起こりません(または1時間以内に停止しません)。私がやろうとしているのは、データフレーム(データ)をより小さなデータフレームに分割し、これらをリスト(データリスト)に追加することです。
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
エラーメッセージは表示されません。スクリプトは永久に実行されるようです。
それを行うスマートな方法はありますか?
まず、新しいエントリ用のスペースが不足しているときに定期的にリストを拡大する必要があるため、行ごとのリストへの追加が遅くなるため、あなたのアプローチは非効率的です。サイズが決定されると、この点でリストの理解度が優れています前部および一度割り当てられて。
ただし、データフレームがすでにあるため、基本的にあなたのアプローチは少し無駄です。なぜこれらのユーザーごとに新しいフレームを作成するのですか?
データフレームを列'name'
で並べ替え、インデックスをこれに設定し、必要に応じて列を削除しません。
次に、すべての一意のエントリのリストを生成してから、これらのエントリを使用してルックアップを実行できます。データを照会するだけの場合は非常に重要です。
そう:
# sort the dataframe
df.sort(columns=['name'], 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'
sort
は非推奨になりました。今すぐsort_values
を使用する必要があります。
# 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'
データフレームをスライスするだけでそれをしないのはなぜですか。何かのようなもの
#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']
役立つことを願っています
groupby
オブジェクトを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
推奨 ではありませんが、グループごとにDataFrameを作成できます:
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
Groupbyは次のことに役立ちます。
grouped = data.groupby(['name'])
その後、各参加者のデータフレームのように、各グループで作業できます。 (apply、transform、aggregate、head、first、last)などのDataFrameGroupByオブジェクトメソッドは、DataFrameオブジェクトを返します。
または、grouped
からリストを作成し、インデックスですべてのDataFrameを取得できます。
l_grouped = list(grouped)
l_grouped[0][1]
-名を持つ最初のグループのDataFrame。
簡単:
[v for k, v in df.groupby('name')]
Gusev Slavaの答えに加えて、groupbyのグループを使用することもできます。
{key: df.loc[value] for key, value in df.groupby("name").groups.items()}
これにより、グループ化したキーを持つディクショナリが生成され、対応するパーティションをポイントします。利点は、キーが保持され、リストインデックスで消えないことです。
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)
合計は皮肉化されているため、これは非常に高速です
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
データのラベルが既にある場合は、groupbyコマンドを使用できます。
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
of two 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