【问题标题】:How to create multiple columns efficiently in Pandas Dataframe如何在 Pandas Dataframe 中高效地创建多列
【发布时间】:2022-01-23 18:19:03
【问题描述】:

我正在尝试使用某些条件在具有大约 450k 条记录的数据框中添加大约 2000 列,但这需要很多时间。有人可以为此提供省时的解决方案。示例代码是这样的-

dict1={x:x for x in range(2000)}
Data = pd.DataFrame(np.random.randint(0,10000,size=(450000, 4)), columns=list('ABCD'))
for i in range(1,2000):
    Data[f'A_{i}']= Data['A'].apply(lambda x: max(0,min(5000,x) -dict1[i]))

【问题讨论】:

  • 您能否提供minimal reproducible example 示例输入和预期输出?矢量化解决方案可以很容易地外推到更大的用例。
  • max(0, min(5000))是你的真实情况吗?
  • @MichaelSzczesny 如果您运行前两行,那是我的输入。我实际上是在客户网站上工作,所以不能提供确切的细节,但它在类似的线上。我希望在我提供的条件下添加 2000 列,例如 A_1、A_2...A_2000
  • @Corralien 是的,只是 5000 将通过另一个变量传递,值可能会有所不同,所以为了简单起见,我放了 5000 而不是变量
  • @AbhishekDwivedi 如果您提供 Micheal 谈到的最小可重复示例,那么是的

标签: python pandas performance apply multiple-columns


【解决方案1】:

这段代码的速度提高了大约 250 倍。我正在使用:

  • int16 减少内存使用量
  • np.clip 而不是缓慢应用 minmax
  • 广播(重塑为 `(-1, 1),反之亦然)
  • 从所有列中创建数据框,而不是迭代地附加每一列
import numpy as np
import pandas as pd
from copy import deepcopy

# converting to int16 everywhere to decrease RAM usage, you can remove it
dict1={x:x for x in range(2000)}
Data = pd.DataFrame(np.random.randint(0,10000,size=(450000, 4)).astype(np.int16), columns=list('ABCD'))
Data2 = deepcopy(Data) # copying data for later comparison, you can remove it

# # OP version, only 20 columns
for i in range(0, 20):  # fixed this for you, because you started iterating from 1 instead of 0
    Data[f'A_{i}']= Data['A'].apply(lambda x: max(0,min(5000,x) -dict1[i]))

# new version, 2000 columns:
# using np.clip that is much faster than DataFrame.apply
Data_A_values_clipped = np.clip(Data['A'].values, None, 5000)
all_dict_values = np.array(list(dict1.values())[:2000]).astype(np.int16)

# using broadcastring is much faster than iterating
new_columns = np.clip(Data_A_values_clipped.reshape(1, -1) - all_dict_values.reshape(-1, 1), 0, None)

new_columns = {f'A_{i}': new_columns[i] for i in range(2000)}
# creating new dataframe out of new data and merging with the
Data2 = pd.concat([Data2, pd.DataFrame(new_columns)], axis=1)

# I checked for 20 columns, is ok:
# assert np.all(Data.values == Data2.values)
# print('well done')

【讨论】:

    猜你喜欢
    • 2022-11-27
    • 2021-03-04
    • 1970-01-01
    • 1970-01-01
    • 2017-12-09
    • 1970-01-01
    • 2020-03-18
    • 2016-07-14
    • 2019-08-31
    相关资源
    最近更新 更多