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,对大熊猫数据框的操作的主要内容,如果未能解决你的问题,请参考以下文章

熊猫:使用数据框的多列作为另一个的索引

序列化包含熊猫数据框的字典(Python)

创建由多个数据框组成的多级熊猫数据框的最快方法是啥?

在给定“映射数据框”的情况下爆炸熊猫数据框的行

带有大熊猫数据框的python代码很慢

如何在python中获取熊猫数据框的行列表? [复制]