データフレームで行をx回複製する-パフォーマンスを向上させる[複製]
Aug 24 2020
データフレーム行を複製するための最も効率的なソリューションを探しています。各行はx回複製する必要があります。ここで、xは各行で一意です。
これが私の与えられたデータフレームであるとしましょう:
| id | count |
|----|-------|
| a | 1 |
| b | 2 |
| c | 5 |
結果として、データフレームは次のようになります。各行は、列「count」で指定された量だけ複製されました。
| id | count |
|----|-------|
| a | 1 |
| b | 2 |
| b | 2 |
| c | 5 |
| c | 5 |
| c | 5 |
| c | 5 |
| c | 5 |
非常に基本的なアプローチは、データフレームをループし、次のように行をx回追加することです。
data = {'id': ['a', 'b', 'c'], 'count': [1, 2, 5]}
df = pd.DataFrame(data=data)
for index, row in df.iterrows():
for x in range(row['count']-1):
df = df.append(pd.Series(row, index=df.columns), ignore_index=True)
df = df.sort_values(by=['id'])
df = df.reset_index(drop=True)
df
これは小さなデータフレームでは機能しますが、数千行の大きなデータフレームではあまり効率的ではありません。各行は最大200回複製する必要があるため、最終的なデータフレームには数百万行を含めることができます。
すでにパンダ/ numpyのベクトル化について読んでいますが、残念ながら、データフレームに多くの行を追加する必要があるこの場合に役立つかどうか(およびどのように役立つか)はわかりません。
パフォーマンスを改善する方法について何か提案はありますか?
回答
4 jezrael Aug 24 2020 at 20:10
Index.repeat一意のインデックス値の場合に使用してから、DataFrame.loc:に渡します。
df1 = df.loc[df.index.repeat(df['count'])].reset_index(drop=True)
print (df1)
id count
0 a 1
1 b 2
2 b 2
3 c 5
4 c 5
5 c 5
6 c 5
7 c 5
可能であれば、インデックス値のいくつかの重複が可能使用であるnumpy.repeatとDataFrame.iloc:
print (df)
id count
0 a 1
1 b 2
1 c 5
df1 = df.iloc[np.repeat(np.arange(len(df.index)), df['count'])].reset_index(drop=True)
print (df1)
id count
0 a 1
1 b 2
2 b 2
3 c 5
4 c 5
5 c 5
6 c 5
7 c 5
1 sammywemmy Aug 24 2020 at 20:14
次のcount列を使用してインデックスを再作成できます。
df.reindex(df.index.repeat(df["count"])).reset_index(drop=True)
DarshShukla Aug 24 2020 at 21:49
In [1]: import numpy as np
...: import pandas as pd
In [2]: data = {'id':list(map(chr, range(97, 123))), 'count': pd.Series(np.random.randint(0,500,size
...: =26))}
In [3]: df = pd.DataFrame(data)
In [4]: df.head()
Out[4]:
id count
0 a 145
1 b 297
2 c 46
3 d 493
4 e 46
In [5]: df_replicate = pd.DataFrame(np.repeat(df.values, df['count'], axis=0),columns=df.columns)
In [6]: df_replicate.head()
Out[6]:
id count
0 a 145
1 a 145
2 a 145
3 a 145
4 a 145