1. ホーム
  2. python

[解決済み] Pandasのデータフレームの連続したチャンクを効率的に反復処理する方法

2023-05-02 10:13:30

質問

大きなデータフレーム(数百万行)があります。

しかし、どのグループに入るかを決めるために個々の行の特定のプロパティを使用するのではなく、行の任意の連続した(できれば同じサイズの)サブセットによってグループ化したいのです。

使用例です。IPythonの並列マップを介して、各行に関数を適用したいです。関数は一度に1つの行に基づいて結果を計算するので、どの行がどのバックエンドエンジンに行くかは重要ではありません。(少なくとも概念的には。現実にはベクトル化されています)。

こんな感じのことを思いつきました。

# Generate a number from 0-9 for each row, indicating which tenth of the DF it belongs to
max_idx = dataframe.index.max()
tenths = ((10 * dataframe.index) / (1 + max_idx)).astype(np.uint32)

# Use this value to perform a groupby, yielding 10 consecutive chunks
groups = [g[1] for g in dataframe.groupby(tenths)]

# Process chunks in parallel
results = dview.map_sync(my_function, groups)

しかし、これは非常に長ったらしいですし、同じ大きさのチャンクを保証するものではありません。特に、インデックスが疎であったり、非整数であったり、その他もろもろであればなおさらです。

より良い方法について何か提案はありますか?

ありがとうございます!

どのように解決するのですか?

実際には を保証することはできません。 等しいサイズのチャンクを保証することはできません。行数 (N) は素数かもしれませんが、その場合は 1 か N でしか同じサイズのチャンクを得られません。このため、現実のチャンキングでは通常、固定サイズを使用して、最後に小さいチャンクを許容しています。私はしばしば、配列を groupby . から開始します。

>>> df = pd.DataFrame(np.random.rand(15, 5), index=[0]*15)
>>> df[0] = range(15)
>>> df
    0         1         2         3         4
0   0  0.746300  0.346277  0.220362  0.172680
0   1  0.657324  0.687169  0.384196  0.214118
0   2  0.016062  0.858784  0.236364  0.963389
[...]
0  13  0.510273  0.051608  0.230402  0.756921
0  14  0.950544  0.576539  0.642602  0.907850

[15 rows x 5 columns]

インデックスを意図的に0にして情報を与えないようにしたところで、単純にサイズ(ここでは10)を決めて、それで配列を整数倍しています。

>>> df.groupby(np.arange(len(df))//10)
<pandas.core.groupby.DataFrameGroupBy object at 0xb208492c>
>>> for k,g in df.groupby(np.arange(len(df))//10):
...     print(k,g)
...     
0    0         1         2         3         4
0  0  0.746300  0.346277  0.220362  0.172680
0  1  0.657324  0.687169  0.384196  0.214118
0  2  0.016062  0.858784  0.236364  0.963389
[...]
0  8  0.241049  0.246149  0.241935  0.563428
0  9  0.493819  0.918858  0.193236  0.266257

[10 rows x 5 columns]
1     0         1         2         3         4
0  10  0.037693  0.370789  0.369117  0.401041
0  11  0.721843  0.862295  0.671733  0.605006
[...]
0  14  0.950544  0.576539  0.642602  0.907850

[5 rows x 5 columns]

DataFrame のスライスに基づくメソッドは、インデックスがそれと互換性がない場合に失敗することがありますが、その場合は、常に .iloc[a:b] を使ってインデックスの値を無視し、位置によってデータにアクセスすることができます。