python,对大熊猫数据框的操作
Posted
技术标签:
【中文标题】python,对大熊猫数据框的操作【英文标题】:python, operation on big pandas Dataframe 【发布时间】:2014-09-19 07:41:06 【问题描述】:我有一个名为 Joined 的 Pandas DataFrame,包含 5 个字段:
product | price | percentil_25 | percentil_50 | percentile_75
对于每一行我想这样分类价格:
如果价格低于 percentil_25,我将给该产品等级 1,依此类推
所以我做的是:
classe_final = OrderedDict()
classe_final['sku'] = []
classe_final['class'] = []
for index in range(len(joined)):
classe_final['sku'].append(joined.values[index][0])
if(float(joined.values[index][1]) <= float(joined.values[index][2])):
classe_final['class'].append(1)
elif(float(joined.values[index][2]) < float(joined.values[index][1]) and float(joined.values[index][1]) <= float(joined.values[index][3])):
classe_final['class'].append(2)
elif(float(joined.values[index][3]) < float(joined.values[index][1]) and float(joined.values[index][1]) <= float(joined.values[index][4])):
classe_final['class'].append(3)
else:
classe_final['class'].append(4)
但由于我的 DataFrame 很大,所以需要很长时间。
你知道我怎样才能更快地做到这一点吗?
【问题讨论】:
抱歉,您只是想根据每个百分位数的价格跌幅来确定产品的类别吗?所以 =25 和 对不起,我刚刚注意到您正在使用有序的字典来存储您的值,所以我的回答不正确,您要生产什么?您的代码将生成一个以产品为键的字典,然后是该产品所属价格的每个类别的列表,对吗?你能展示一个玩具样本数据集和预期的输出吗 作为输出,我只想要一个包含 2 个字段的 DataFrame:product |类@EdChum 所以你实际上只是在构建一个分类数据框 【参考方案1】:# build an empty df
df = pd.DataFrame()
# get a list of the unique products, could skip this perhaps
df['Product'] = other_df['Sku'].unique()
2种方式,定义一个func并调用apply
def class(x):
if x.price < x.percentil_25:
return 1
elif x.price >= x.percentil_25 and x.price < x.percentil_50:
return 2:
elif x.price >= x.percentil_50 and x.price < x.percentil_75:
return 2:
elif x.price >= x.percentil_75:
return 4
df['class'] = other_df.apply(lambda row: class(row'), axis=1)
我认为更好且更快的另一种方法是我们可以将“类”列添加到您现有的 df 并使用loc
,然后查看感兴趣的 2 列:
joined.loc[joined['price'] < joined['percentil_25'], 'class'] =1
joined.loc[(joined['price'] >= joined['percentil_25']) & (joined['price'] < joined['percentil_50']), 'class'] =2
joined.loc[(joined['price'] >= joined['percentil_50']) & (joined['price'] < joined['percentil_75']), 'class'] =3
joined.loc[joined['price'] >= joined['percentil_75'], 'class'] =4
classe_final = joined[['cku', 'class']]
只是为了好玩,您可以使用np.where
条件的负载:
classe_final['class'] = np.where(joined['price'] > joined['percentil_75'], 4, np.where( joined['price'] > joined['percentil_50'], 3, np.where( joined['price'] > joined['percentil_25'], 2, 1 ) ) )
这会评估价格是否大于 percentil_75,如果是,那么第 4 类,否则它会评估另一个条件,依此类推,与 loc 相比可能值得计时,但它的可读性要差很多
【讨论】:
谢谢,我肯定在使用第二种解决方案!速度很快,再次感谢! @user1754181 你也可以投票;),要避免循环并使用 apply 除非不可能,你想要做的是找到你是否矢量化你的操作,即对整个数据框或系列执行操作,而不是一次对一行执行操作。 是的,我明白你的意思,我更习惯 sql,pandas 对我来说有点新【参考方案2】:另一种解决方案,如果有人让我打赌哪个是最快的,我会这样做:
joined.set_index("product").eval(
"1 * (price >= percentil_25)"
" + (price >= percentil_50)"
" + (price >= percentil_75)"
)
【讨论】:
它更多的是在可读性和可维护性方面的改进,而不是在性能方面:)。不过没有测试,loc
相当快。 @user1754181,你有可用的测试数据吗?
在我的机器上检查最后一个实现比接受的解决方案快一个数量级(30ms vs 300ms 在具有 1M 行的数据帧上)。以上是关于python,对大熊猫数据框的操作的主要内容,如果未能解决你的问题,请参考以下文章