性能警告:添加更多列时,DataFrame 高度碎片化

问题描述 投票:0回答:2

在数据框中插入新列(这些列是现有列的移位副本)时,我收到此警告。我怎样才能重写这段代码以避免警告?我发现的一个解决方案是在每次插入后复制整个数据帧,但这似乎效率低下。

data = {str(i):[pow(k, i) for k in range(1000)] for i in range(1, 6)}
df = pd.DataFrame.from_dict(data)
for col in df.columns:
    for offset in range(1, 30):
        df[f'{col}-{offset}'] = df[col].shift(offset)
        # df = df.copy() # solved the problem, but likely not best solution
python pandas dataframe
2个回答
0
投票

您可以一次

shift
整个 DataFrame 并
concat
输出:

out = df.join(pd.concat({offset: df.shift(offset) for offset in range(1, 30)}, axis=1)
                .sort_index(axis=1, level=1)
                .pipe(lambda d: d.set_axis(d.columns.map(lambda x: f'{x[1]}-{x[0]}'), axis=1))
             )

输出(尺寸较小的示例):

   1   2    3     4      5  1-1  1-2  1-3  1-4  1-5  1-6  1-7  1-8  1-9   2-1   2-2   2-3   2-4   2-5  2-6  2-7  2-8  2-9    3-1    3-2    3-3    3-4   3-5   3-6  3-7  3-8  3-9     4-1     4-2     4-3    4-4    4-5   4-6   4-7  4-8  4-9      5-1      5-2     5-3     5-4     5-5    5-6   5-7  5-8  5-9
0  0   0    0     0      0  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN   NaN   NaN   NaN   NaN   NaN  NaN  NaN  NaN  NaN    NaN    NaN    NaN    NaN   NaN   NaN  NaN  NaN  NaN     NaN     NaN     NaN    NaN    NaN   NaN   NaN  NaN  NaN      NaN      NaN     NaN     NaN     NaN    NaN   NaN  NaN  NaN
1  1   1    1     1      1  0.0  NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN   0.0   NaN   NaN   NaN   NaN  NaN  NaN  NaN  NaN    0.0    NaN    NaN    NaN   NaN   NaN  NaN  NaN  NaN     0.0     NaN     NaN    NaN    NaN   NaN   NaN  NaN  NaN      0.0      NaN     NaN     NaN     NaN    NaN   NaN  NaN  NaN
2  2   4    8    16     32  1.0  0.0  NaN  NaN  NaN  NaN  NaN  NaN  NaN   1.0   0.0   NaN   NaN   NaN  NaN  NaN  NaN  NaN    1.0    0.0    NaN    NaN   NaN   NaN  NaN  NaN  NaN     1.0     0.0     NaN    NaN    NaN   NaN   NaN  NaN  NaN      1.0      0.0     NaN     NaN     NaN    NaN   NaN  NaN  NaN
3  3   9   27    81    243  2.0  1.0  0.0  NaN  NaN  NaN  NaN  NaN  NaN   4.0   1.0   0.0   NaN   NaN  NaN  NaN  NaN  NaN    8.0    1.0    0.0    NaN   NaN   NaN  NaN  NaN  NaN    16.0     1.0     0.0    NaN    NaN   NaN   NaN  NaN  NaN     32.0      1.0     0.0     NaN     NaN    NaN   NaN  NaN  NaN
4  4  16   64   256   1024  3.0  2.0  1.0  0.0  NaN  NaN  NaN  NaN  NaN   9.0   4.0   1.0   0.0   NaN  NaN  NaN  NaN  NaN   27.0    8.0    1.0    0.0   NaN   NaN  NaN  NaN  NaN    81.0    16.0     1.0    0.0    NaN   NaN   NaN  NaN  NaN    243.0     32.0     1.0     0.0     NaN    NaN   NaN  NaN  NaN
5  5  25  125   625   3125  4.0  3.0  2.0  1.0  0.0  NaN  NaN  NaN  NaN  16.0   9.0   4.0   1.0   0.0  NaN  NaN  NaN  NaN   64.0   27.0    8.0    1.0   0.0   NaN  NaN  NaN  NaN   256.0    81.0    16.0    1.0    0.0   NaN   NaN  NaN  NaN   1024.0    243.0    32.0     1.0     0.0    NaN   NaN  NaN  NaN
6  6  36  216  1296   7776  5.0  4.0  3.0  2.0  1.0  0.0  NaN  NaN  NaN  25.0  16.0   9.0   4.0   1.0  0.0  NaN  NaN  NaN  125.0   64.0   27.0    8.0   1.0   0.0  NaN  NaN  NaN   625.0   256.0    81.0   16.0    1.0   0.0   NaN  NaN  NaN   3125.0   1024.0   243.0    32.0     1.0    0.0   NaN  NaN  NaN
7  7  49  343  2401  16807  6.0  5.0  4.0  3.0  2.0  1.0  0.0  NaN  NaN  36.0  25.0  16.0   9.0   4.0  1.0  0.0  NaN  NaN  216.0  125.0   64.0   27.0   8.0   1.0  0.0  NaN  NaN  1296.0   625.0   256.0   81.0   16.0   1.0   0.0  NaN  NaN   7776.0   3125.0  1024.0   243.0    32.0    1.0   0.0  NaN  NaN
8  8  64  512  4096  32768  7.0  6.0  5.0  4.0  3.0  2.0  1.0  0.0  NaN  49.0  36.0  25.0  16.0   9.0  4.0  1.0  0.0  NaN  343.0  216.0  125.0   64.0  27.0   8.0  1.0  0.0  NaN  2401.0  1296.0   625.0  256.0   81.0  16.0   1.0  0.0  NaN  16807.0   7776.0  3125.0  1024.0   243.0   32.0   1.0  0.0  NaN
9  9  81  729  6561  59049  8.0  7.0  6.0  5.0  4.0  3.0  2.0  1.0  0.0  64.0  49.0  36.0  25.0  16.0  9.0  4.0  1.0  0.0  512.0  343.0  216.0  125.0  64.0  27.0  8.0  1.0  0.0  4096.0  2401.0  1296.0  625.0  256.0  81.0  16.0  1.0  0.0  32768.0  16807.0  7776.0  3125.0  1024.0  243.0  32.0  1.0  0.0

0
投票

您可以将新列收集到列表中,然后使用

pd.concat

columns = []
for col in df.columns:
    for offset in range(1, 30):
        columns.append(df[col].shift(offset))

pd.concat([df, *columns], axis=1)
© www.soinside.com 2019 - 2024. All rights reserved.