Pandas:删除少于 2 个非零值的项目
Pandas: Remove Items who has less than 2 non-zero values
我有一个数据框,其中包含所有 317 个不同的 ProductCode 和每周销售数量列的连续 30 个每周日期,如下所示:
Date ProductCode Weekly_Units_Sold
2015-08-09 1 46.0
2015-08-09 2 46.0
2015-08-09 3 31.0
... ... ...
2015-08-09 317 47.0
2015-08-16 1 0
2015-08-16 2 46.0
2015-08-16 3 31.0
... ...
2015-08-16 317 75.0
2015-08-23 1 0.0
2015-08-23 2 90.0
2015-08-23 3 175.0
.... ...
2015-08-23 317 20.0
.... ... ..
2015-12-27 1 0.0
2015-12-27 2 30.0
2015-12-27 3 150.0
.... ...
2015-12-27 317 20.0
我正在尝试检查每个 ProductCode 的 Weekly_Units_Sold,是否有任何 ProductCode 在 Weekly_Units_Sold 中具有少于 2 个非零值;代码应该删除属于检测到的 ProductCode 的所有行。
假设已检测到 ProductCode 1 在 Weekly_Units_Sold 列值中只有 1 个非零值,其 29 个其他值均为 0 。想要从数据框中删除属于 ProductCode 1 的所有 30 行,
Date ProductCode Weekly_Units_Sold
2015-08-09 2 46.0
2015-08-09 3 31.0
... ... ...
2015-08-09 317 47.0
2015-08-16 2 46.0
2015-08-16 3 31.0
... ...
2015-08-16 317 75.0
2015-08-23 2 90.0
2015-08-23 3 175.0
.... ...
2015-08-23 317 20.0
.... ... ..
2015-12-27 2 30.0
2015-12-27 3 150.0
.... ...
2015-12-27 317 20.0
做 tihs 的最佳 Pythonistic 方法是什么?
谢谢!
我对您的示例数据进行了一些编辑,以便构建一个工作示例。
Date ProductCode Weekly_Units_Sold
2015-08-09 1 46.0
2015-08-09 2 46.0
2015-08-09 3 31.0
2015-08-09 317 47.0
2015-08-16 1 0
2015-08-16 2 46.0
2015-08-16 3 31.0
2015-08-16 317 75.0
2015-08-23 1 0.0
2015-08-23 2 90.0
2015-08-23 3 175.0
2015-08-23 317 20.0
2015-12-27 1 0.0
2015-12-27 2 30.0
2015-12-27 3 150.0
2015-12-27 317 20.0
这里我们从上述数据的 pd.read_clipboard() 开始。
df = pd.read_clipboard()
print(df)
Date ProductCode Weekly_Units_Sold
0 2015-08-09 1 46.0
1 2015-08-09 2 46.0
2 2015-08-09 3 31.0
3 2015-08-09 317 47.0
4 2015-08-16 1 0.0
5 2015-08-16 2 46.0
6 2015-08-16 3 31.0
7 2015-08-16 317 75.0
8 2015-08-23 1 0.0
9 2015-08-23 2 90.0
10 2015-08-23 3 175.0
11 2015-08-23 317 20.0
12 2015-12-27 1 0.0
13 2015-12-27 2 30.0
14 2015-12-27 3 150.0
15 2015-12-27 317 20.0
我们按 ProductCode 分组并创建 Weekly_Units_Sold 列中所有 Weekly_Units_Sold 值的字符串列表。
df_gb = df.groupby(['ProductCode'])['Weekly_Units_Sold'].apply(list).to_frame()
print(df_gb)
Weekly_Units_Sold
ProductCode
1 [46.0, 0.0, 0.0, 0.0]
2 [46.0, 46.0, 90.0, 30.0]
3 [31.0, 31.0, 175.0, 150.0]
317 [47.0, 75.0, 20.0, 20.0]
接下来我们可以使用 lambda 和 np.count_nonzero 为产品代码提供 < 2 个非零值的布尔值。
df_gb['non_zero_lt_two'] = df_gb['Weekly_Units_Sold'].apply(lambda x: True if np.count_nonzero(np.array(x)) < 2 else False)
打印(df_gb)
Weekly_Units_Sold non_zero_lt_two
ProductCode
1 [46.0, 0.0, 0.0, 0.0] True
2 [46.0, 46.0, 90.0, 30.0] False
3 [31.0, 31.0, 175.0, 150.0] False
317 [47.0, 75.0, 20.0, 20.0] False
然后我们可以将真值行变成一个列表。
prod_code_list = df_gb.index[df_gb['non_zero_lt_two'] == True].tolist()
然后最后从原始 df 中删除所需的行。
df = df[~df['ProductCode'].isin(prod_code_list)]
print(df)
Date ProductCode Weekly_Units_Sold
1 2015-08-09 2 46.0
2 2015-08-09 3 31.0
3 2015-08-09 317 47.0
5 2015-08-16 2 46.0
6 2015-08-16 3 31.0
7 2015-08-16 317 75.0
9 2015-08-23 2 90.0
10 2015-08-23 3 175.0
11 2015-08-23 317 20.0
13 2015-12-27 2 30.0
14 2015-12-27 3 150.0
15 2015-12-27 317 20.0
我有一个数据框,其中包含所有 317 个不同的 ProductCode 和每周销售数量列的连续 30 个每周日期,如下所示:
Date ProductCode Weekly_Units_Sold
2015-08-09 1 46.0
2015-08-09 2 46.0
2015-08-09 3 31.0
... ... ...
2015-08-09 317 47.0
2015-08-16 1 0
2015-08-16 2 46.0
2015-08-16 3 31.0
... ...
2015-08-16 317 75.0
2015-08-23 1 0.0
2015-08-23 2 90.0
2015-08-23 3 175.0
.... ...
2015-08-23 317 20.0
.... ... ..
2015-12-27 1 0.0
2015-12-27 2 30.0
2015-12-27 3 150.0
.... ...
2015-12-27 317 20.0
我正在尝试检查每个 ProductCode 的 Weekly_Units_Sold,是否有任何 ProductCode 在 Weekly_Units_Sold 中具有少于 2 个非零值;代码应该删除属于检测到的 ProductCode 的所有行。
假设已检测到 ProductCode 1 在 Weekly_Units_Sold 列值中只有 1 个非零值,其 29 个其他值均为 0 。想要从数据框中删除属于 ProductCode 1 的所有 30 行,
Date ProductCode Weekly_Units_Sold
2015-08-09 2 46.0
2015-08-09 3 31.0
... ... ...
2015-08-09 317 47.0
2015-08-16 2 46.0
2015-08-16 3 31.0
... ...
2015-08-16 317 75.0
2015-08-23 2 90.0
2015-08-23 3 175.0
.... ...
2015-08-23 317 20.0
.... ... ..
2015-12-27 2 30.0
2015-12-27 3 150.0
.... ...
2015-12-27 317 20.0
做 tihs 的最佳 Pythonistic 方法是什么? 谢谢!
我对您的示例数据进行了一些编辑,以便构建一个工作示例。
Date ProductCode Weekly_Units_Sold
2015-08-09 1 46.0
2015-08-09 2 46.0
2015-08-09 3 31.0
2015-08-09 317 47.0
2015-08-16 1 0
2015-08-16 2 46.0
2015-08-16 3 31.0
2015-08-16 317 75.0
2015-08-23 1 0.0
2015-08-23 2 90.0
2015-08-23 3 175.0
2015-08-23 317 20.0
2015-12-27 1 0.0
2015-12-27 2 30.0
2015-12-27 3 150.0
2015-12-27 317 20.0
这里我们从上述数据的 pd.read_clipboard() 开始。
df = pd.read_clipboard()
print(df)
Date ProductCode Weekly_Units_Sold
0 2015-08-09 1 46.0
1 2015-08-09 2 46.0
2 2015-08-09 3 31.0
3 2015-08-09 317 47.0
4 2015-08-16 1 0.0
5 2015-08-16 2 46.0
6 2015-08-16 3 31.0
7 2015-08-16 317 75.0
8 2015-08-23 1 0.0
9 2015-08-23 2 90.0
10 2015-08-23 3 175.0
11 2015-08-23 317 20.0
12 2015-12-27 1 0.0
13 2015-12-27 2 30.0
14 2015-12-27 3 150.0
15 2015-12-27 317 20.0
我们按 ProductCode 分组并创建 Weekly_Units_Sold 列中所有 Weekly_Units_Sold 值的字符串列表。
df_gb = df.groupby(['ProductCode'])['Weekly_Units_Sold'].apply(list).to_frame()
print(df_gb)
Weekly_Units_Sold
ProductCode
1 [46.0, 0.0, 0.0, 0.0]
2 [46.0, 46.0, 90.0, 30.0]
3 [31.0, 31.0, 175.0, 150.0]
317 [47.0, 75.0, 20.0, 20.0]
接下来我们可以使用 lambda 和 np.count_nonzero 为产品代码提供 < 2 个非零值的布尔值。
df_gb['non_zero_lt_two'] = df_gb['Weekly_Units_Sold'].apply(lambda x: True if np.count_nonzero(np.array(x)) < 2 else False)
打印(df_gb)
Weekly_Units_Sold non_zero_lt_two
ProductCode
1 [46.0, 0.0, 0.0, 0.0] True
2 [46.0, 46.0, 90.0, 30.0] False
3 [31.0, 31.0, 175.0, 150.0] False
317 [47.0, 75.0, 20.0, 20.0] False
然后我们可以将真值行变成一个列表。
prod_code_list = df_gb.index[df_gb['non_zero_lt_two'] == True].tolist()
然后最后从原始 df 中删除所需的行。
df = df[~df['ProductCode'].isin(prod_code_list)]
print(df)
Date ProductCode Weekly_Units_Sold
1 2015-08-09 2 46.0
2 2015-08-09 3 31.0
3 2015-08-09 317 47.0
5 2015-08-16 2 46.0
6 2015-08-16 3 31.0
7 2015-08-16 317 75.0
9 2015-08-23 2 90.0
10 2015-08-23 3 175.0
11 2015-08-23 317 20.0
13 2015-12-27 2 30.0
14 2015-12-27 3 150.0
15 2015-12-27 317 20.0