【问题标题】:How to filter a dataframe and identify records based on a condition on multiple other columns如何根据多个其他列上的条件过滤数据框并识别记录
【发布时间】:2022-01-03 18:54:37
【问题描述】:
id zone price
0 0000001 1 33.0
1 0000001 2 24.0
2 0000001 3 34.0
3 0000001 4 45.0
4 0000001 5 51.0
我有上面的 pandas 数据框,这里有多个 id(这里只显示了 1 个 id)。数据框由具有 5 个区域和 5 个价格的特定 ID 组成。这些价格应遵循以下模式
p1(1区价格)如果出现任何异常,我们应该识别异常记录并将其打印到文件中。
在这个例子中 p3 p2 而 p1
因此应将第一 2 条记录打印到文件中
同样,必须对其中所有唯一 ID 的整个数据框执行此操作
我的数据框很大,进行此过滤和识别错误记录的最有效方法是什么?
【问题讨论】:
标签:
python
pandas
dataframe
filter
【解决方案1】:
另一种方法是首先通过ascending 订单中的id 和区域sort 您的数据框,然后使用groupby.shift() 创建一个新列将下一个价格与之前的价格进行比较。然后你可以打印出价值下降的价格:
import numpy as np
import pandas as pd
df.sort_values(by=['id','zone'],ascending=True)
df['increase'] = np.where(df.zone.eq(1),'no change',
np.where(df.groupby('id')['price'].shift(1) < df['price'],'inc','dec'))
>>> df
id zone price increase
0 1 1 33 no change
1 1 2 24 dec
2 1 3 34 inc
3 1 4 45 inc
4 1 5 51 inc
5 2 1 34 no change
6 2 2 56 inc
7 2 3 22 dec
8 2 4 55 inc
9 2 5 77 inc
10 3 1 44 no change
11 3 2 55 inc
12 3 3 44 dec
13 3 4 66 inc
14 3 5 33 dec
>>> df.loc[df.increase.eq('dec')]
id zone price increase
1 1 2 24 dec
7 2 3 22 dec
12 3 3 44 dec
14 3 5 33 dec
我添加了一些额外的 ID 来尝试模仿您的真实数据。
【解决方案2】:
您可以在对值进行排序后计算每个组的diff,以确保区域不断增加。如果 diff ≤ 0,则价格不会严格增加,应标记行:
s = (df.sort_values(by=['id', 'zone']) # sort rows
.groupby('id') # group by id
['price'].diff() # compute the diff
.le(0) # flag those ≤ 0 (not increasing)
)
df[s|s.shift(-1)] # slice flagged rows + previous row
示例输出:
id zone price
0 1 1 33.0
1 1 2 24.0
示例输入:
id zone price
0 1 1 33.0
1 1 2 24.0
2 1 3 34.0
3 1 4 45.0
4 1 5 51.0
5 2 1 20.0
6 2 2 24.0
7 2 3 34.0
8 2 4 45.0
9 2 5 51.0
保存到文件
df[s|s.shift(-1)].to_csv('incorrect_prices.csv')