我正在尝试根据每个groupby的条件创建新的数据框。 假设我有一个带有名称,标志和月份的数据框。
import pandas as pd
import numpy as np
data = {'Name':['A', 'A', 'B', 'B'], 'Flag':[0, 1, 0, 1], 'Month':[1,2,1,2]}
df = pd.DataFrame(data)
need = df.loc[df['Flag'] == 0].groupby(['Name'], as_index = False)['Month'].min()
我的条件是查找每个名称的标志等于0的最小月份。
我已经使用.loc
定义了我的条件,它可以正常工作,但是我发现当应用1000万行时,它的性能相当差。
有没有更有效的方法?
谢谢!
答案 0 :(得分:0)
昨天也遇到了同样的情况,我花了90秒的时间将其降低到大约3秒。因为速度是您的关注点(就像我的一样),而不是仅使用熊猫本身,所以我建议您使用Numba和NumPy。问题在于您将不得不重新整理数据结构和类型,以掌握Numba对JIT所做的实际工作。不过,一旦完成,它就会动摇。
我建议找到一种方法来将DataFrame中的每个值都转换为整数。对于您的名称列,请尝试使用唯一ID。国旗和月份已经看起来不错。
name_ids = []
for i, name in enumerate(np.unique(df["Name"])):
name_ids.append({i: name})
然后,创建一个函数并循环使用老式方法:
@njit
def really_fast_numba_loop(data):
for row in data:
# do stuff
return data
new_df = really_fast_numba_loop(data)
第一次在文件中调用函数时,其速度与其他地方的速度大致相同,但在所有其他情况下,它的速度很快。因此,诀窍是在函数中添加内容与外部循环中添加内容之间取得平衡。
无论哪种情况,当您完成对值的处理后,请将name_ids
转换回字符串并将数据包装在pd.DataFrame
中。
瞧。您只是击败了Pandas的iterrows / itertuples。
如有任何疑问,请回来评论!