python - Jupyter Pandas - 丢弃平均值超过阈值的项目

标签 python pandas dataframe jupyter vaex

我有一个包含商品及其价格的数据框,如下所示: ╔══════╦═════╦═══════╗ ║ 商品 ║ 日期 ║ 价格 ║ ╠══════╬═════╬═══════╣ ║ A ║ 1 ║ 10 ║ ║ B ║ 1 ║ 20 ║ ║ C ║ 1 ║ 30 ║ ║ D ║ 1 ║ 40 ║ ║ A ║ 2 ║ 100 ║ ║ B ║ 2 ║ 20 ║ ║ C ║ 2 ║ 30 ║ ║ D ║ 2 ║ 40 ║ ║ A ║ 3 ║ 500 ║ ║ B ║ 3 ║ 25 ║ ║ C ║ 3 ║ 35 ║ ║ D ║ 3 ║ 1000 ║ ╚══════╩═════╩═══════╝

我想从该 df 中排除该商品的平均价格超过 200 的所有行。因此过滤后的 df 应如下所示: ╔══════╦═════╦═══════╗ ║ 商品 ║ 日期 ║ 价格 ║ ╠══════╬═════╬═══════╣ ║ B ║ 1 ║ 20 ║ ║ C ║ 1 ║ 30 ║ ║ B ║ 2 ║ 20 ║ ║ C ║ 2 ║ 30 ║ ║ B ║ 3 ║ 25 ║ ║ C ║ 3 ║ 35 ║ ╚══════╩═════╩═══════╝

我是 python 和 pandas 的新手,但第一步是考虑这样的事情来获取平均价格的新 df: avg_prices_df = df.groupby('ItemID').Price.mean().reset_index 然后不知道如何从那里继续。甚至不确定第一步是否正确。

为了使问题更加复杂,我使用 vaex 读取 ndf5 形式的数据,因为我有超过 4 亿行。

提前非常感谢您的任何建议。

编辑:所以我得到了以下代码,尽管我确信它没有优化..

`

创建 ItemID 及其平均价格的数据框

df_item_avg_price = df.groupby(df.ItemID, agg=[vaex.agg.count('ItemID'), vaex.agg.mean('价格')])

按平均价格阈值过滤此新数据框

df_item_avg_price = (df_item_avg_price[df_item_avg_price["P_r_i_c_e_mean"] <= 50000000])

创建平均价格低于阈值的 ItemID 列表

items_in_price_range = df_item_avg_price['ItemID'].tolist()

过滤原始数据框以仅包含价格范围内的商品的行

filtered_df = df[df.ItemID.isin(items_in_price_range)] ` 有更好的方法吗?

最佳答案

使用GroupBy.transform对于与原始大小相同的每个组的平均值,因此可以通过 boolean indexing 过滤掉所有均值小于 200 的组:

avg_prices_df = df[df.groupby('Item')['Price'].transform('mean') < 200]

另一个解决方案 DataFrameGroupBy.filter :

avg_prices_df = df.groupby('Item').filter(lambda x: x['Price'].mean() < 200)
<小时/>
print (avg_prices_df)
   Item  Day  Price
1     B    1     20
2     C    1     30
5     B    2     20
6     C    2     30
9     B    3     25
10    C    3     35

print (df.groupby('Item')['Price'].transform('mean'))
0     203.333333
1      21.666667
2      31.666667
3     360.000000
4     203.333333
5      21.666667
6      31.666667
7     360.000000
8     203.333333
9      21.666667
10     31.666667
11    360.000000
Name: Price, dtype: float64

vaex 的解决方案:

df_item_avg_price = df.groupby(df.ItemID).agg({'Price' : 'mean'})
df_item_avg_price = (df_item_avg_price[df_item_avg_price["Price"] <= 200])

df = df_item_avg_price.drop(['Price']).join(df, on='ItemID')
print (df)
  ItemID  Day  Price
0      B    1     20
1      B    2     20
2      B    3     25
3      C    1     30
4      C    2     30
5      C    3     35

关于python - Jupyter Pandas - 丢弃平均值超过阈值的项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59233282/

相关文章:

python - Pandas :合并数据框和系列/填充缺失的数据点

python - Tensorflow 1.6 中的 SSD_MOBILENET V1 到 TensorRT

python - 如何将 apply() 函数用于单个列?

python - 如何有条件地替换 pandas 数据框列中的子字符串?

python - 最知名的用户交叉匹配事件算法是什么?

python - 如何使用 winrm+Python 将文件上传到 Windows 机器

python - 如何在数据框的数组列中选择一个元素?

python - 打印 pandas 数据框时如何在标题中包含列类型?

string - 从CSV文件读取的数据帧中删除级别-R

python - 接收未知列数的 Spark UDF