web-dev-qa-db-ja.com

データフレームを複数のデータフレームに分割する

非常に大きなデータフレーム(約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

エラーメッセージは表示されません。スクリプトは永久に実行されるようです。

それを行うスマートな方法はありますか?

61

まず、新しいエントリ用のスペースが不足しているときに定期的にリストを拡大する必要があるため、行ごとのリストへの追加が遅くなるため、あなたのアプローチは非効率的です。サイズが決定されると、この点でリストの理解度が優れています前部および一度割り当てられて。

ただし、データフレームがすでにあるため、基本的にあなたのアプローチは少し無駄です。なぜこれらのユーザーごとに新しいフレームを作成するのですか?

データフレームを列'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'
41
EdChum

データフレームをスライスするだけでそれをしないのはなぜですか。何かのようなもの

#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']

役立つことを願っています

54
Woody Pride

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
34
jezrael

Groupbyは次のことに役立ちます。

grouped = data.groupby(['name'])

その後、各参加者のデータフレームのように、各グループで作業できます。 (apply、transform、aggregate、head、first、last)などのDataFrameGroupByオブジェクトメソッドは、DataFrameオブジェクトを返します。

または、groupedからリストを作成し、インデックスですべてのDataFrameを取得できます。

l_grouped = list(grouped)

l_grouped[0][1]-名を持つ最初のグループのDataFrame。

12
Gusev Slava

簡単:

[v for k, v in df.groupby('name')]
8
Daniel Braun

Gusev Slavaの答えに加えて、groupbyのグループを使用することもできます。

{key: df.loc[value] for key, value in df.groupby("name").groups.items()}

これにより、グループ化したキーを持つディクショナリが生成され、対応するパーティションをポイントします。利点は、キーが保持され、リストインデックスで消えないことです。

4
Quickbeam2k1
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
3
Jeff

リスト内包表記とgroupby-に基づくメソッド。すべての分割データフレームをリスト変数に格納し、インデックスを使用してアクセスできます。

ans = [pd.DataFrame(y) for x, y in DF.groupby('column_name', as_index=False)]

ans[0]
ans[0].column_name
1
Ram Prajapati

データのラベルが既にある場合は、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

0
idnavid