【问题标题】:filtering data from data frame with complex criteria in pandas python在pandas python中从具有复杂标准的数据框中过滤数据
【发布时间】:2022-02-23 19:59:43
【问题描述】:

这是我的数据框

import pandas as pd

data=pd.DataFrame({'vehicle':['car','car','car','car','car','car','bus','bus','bus','bus','bus','bus','car','car','car','car','car','car','bus','bus','bus','bus','bus','bus'],
'expecteddate':['2/24/2022','2/24/2022','3/15/2022','3/15/2022','4/20/2022','4/20/2022','2/24/2022','2/24/2022','3/15/2022','3/15/2022','4/20/2022','4/20/2022','2/24/2022','2/24/2022','3/15/2022','3/15/2022','4/20/2022','4/20/2022','2/24/2022','2/24/2022','3/15/2022','3/15/2022','4/20/2022','4/20/2022'],'range':[240,240,240,240,240,240,300,300,300,300,300,300,240,240,240,240,240,240,300,300,300,300,300,300],'color':['blue','red','blue','red','blue','red','blue','red','blue','red','blue','red','blue','red','blue','red','blue','red','blue','red','blue','red','blue','red'],'discount':[70,80,90,60,40,50,120,110,130,140,80,90,60,40,50,30,70,45,130,100,140,120,90,30],'date':['2/18/2022','2/18/2022','2/18/2022','2/18/2022','2/18/2022','2/18/2022','2/18/2022','2/18/2022','2/18/2022','2/18/2022','2/18/2022','2/18/2022','2/17/2022','2/17/2022','2/17/2022','2/17/2022','2/17/2022','2/17/2022','2/17/2022','2/17/2022','2/17/2022','2/17/2022','2/17/2022','2/17/2022']})
print(data)

数据框中的数据:

   vehicle  expecteddate  range color  discount       date
0      car    2/24/2022    240  blue        70  2/18/2022
1      car    2/24/2022    240   red        80  2/18/2022
2      car    3/15/2022    240  blue        90  2/18/2022
3      car    3/15/2022    240   red        60  2/18/2022
4      car    4/20/2022    240  blue        40  2/18/2022
5      car    4/20/2022    240   red        50  2/18/2022
6      bus    2/24/2022    300  blue       120  2/18/2022
7      bus    2/24/2022    300   red       110  2/18/2022
8      bus    3/15/2022    300  blue       130  2/18/2022
9      bus    3/15/2022    300   red       140  2/18/2022
10     bus    4/20/2022    300  blue        80  2/18/2022
11     bus    4/20/2022    300   red        90  2/18/2022
12     car    2/24/2022    240  blue        60  2/17/2022
13     car    2/24/2022    240   red        40  2/17/2022
14     car    3/15/2022    240  blue        50  2/17/2022
15     car    3/15/2022    240   red        30  2/17/2022
16     car    4/20/2022    240  blue        70  2/17/2022
17     car    4/20/2022    240   red        45  2/17/2022
18     bus    2/24/2022    300  blue       130  2/17/2022
19     bus    2/24/2022    300   red       100  2/17/2022
20     bus    3/15/2022    300  blue       140  2/17/2022
21     bus    3/15/2022    300   red       120  2/17/2022
22     bus    4/20/2022    300  blue        90  2/17/2022
23     bus    4/20/2022    300   red        30  2/17/2022

从这个数据框中,我们有两辆车,三个预期日期,范围,两种颜色,折扣和日期。 我们必须找到折扣中的最小值和我们在折扣列中获得最小值的日期,分成两个新列,即 mindisc 列和 mindate,应该根据最新日期保存在新列中,这应该根据车辆过滤,expecteddate,range,color and date

我们必须在两个日期的折扣列中找到最小值(所有日期,因为我们有很多日期,不限于两个日期)2/18/2022,2/17/2022 基于相同的颜色、范围、预期日期和车辆

最后这个最小值添加到最晚日期的 mindisc 列和 min date 出现在最晚日期行的 minate 列的相应日期

输出应该是这样的

 country expecteddate  range color  discount       date  mindisc    mindate
0      car    2/24/2022    240  blue        70  2/18/2022   60       2/17/2022
1      car    2/24/2022    240   red        80  2/18/2022   40       2/17/2022
2      car    3/15/2022    240  blue        90  2/18/2022   50       2/17/2022
3      car    3/15/2022    240   red        60  2/18/2022   30       2/17/2022
4      car    4/20/2022    240  blue        40  2/18/2022   40       2/18/2022
5      car    4/20/2022    240   red        50  2/18/2022   45       2/17/2022
6      bus    2/24/2022    300  blue       120  2/18/2022   120      2/18/2022
7      bus    2/24/2022    300   red       110  2/18/2022   100      2/17/2022
8      bus    3/15/2022    300  blue       130  2/18/2022   130      2/18/2022
9      bus    3/15/2022    300   red       140  2/18/2022   120      2/17/2022
10     bus    4/20/2022    300  blue        80  2/18/2022   80       2/18/2022
11     bus    4/20/2022    300   red        90  2/18/2022   30       2/17/2022
12     car    2/24/2022    240  blue        60  2/17/2022
13     car    2/24/2022    240   red        40  2/17/2022
14     car    3/15/2022    240  blue        50  2/17/2022
15     car    3/15/2022    240   red        30  2/17/2022
16     car    4/20/2022    240  blue        70  2/17/2022
17     car    4/20/2022    240   red        45  2/17/2022
18     bus    2/24/2022    300  blue       130  2/17/2022
19     bus    2/24/2022    300   red       100  2/17/2022
20     bus    3/15/2022    300  blue       140  2/17/2022
21     bus    3/15/2022    300   red       120  2/17/2022
22     bus    4/20/2022    300  blue        90  2/17/2022
23     bus    4/20/2022    300   red        30  2/17/2022

车辆不限于汽车和公共汽车等两个,它有很多车辆,数据在车辆和范围列中的行并不总是相等,日期不限于两个日期

【问题讨论】:

  • 关于“mindisc”和“mindate”这两个列,其他行的内容应该是什么?您希望 NaN 还是重复这些值?
  • 剩余行的 Nan 值
  • 那么新列不会和其他列有关系吗?我的意思是,新价值观是否以某种方式一致?如果它们与其行无关,是否可以使用不同的数据框?我试图了解如何确定新列的每个值的去向
  • 我们有 2/18/22022,2/17/2022 日期,将 2/18/2022 视为最晚日期,当我们在 discout 列中找到 min 时,应添加数据到特定车辆的最新日期行,预期日期,范围,颜色,请阅读我在您的答案下方评论,例如,以便更好地理解问题

标签: python-3.x pandas


【解决方案1】:

这是我的方法。让我们首先将"date" 列视为一个日期时间对象:

df["date"] = pd.to_datetime(df["date"])

现在,我们可以按照您的描述对数据进行分组,以找到达到最低折扣的行:

common_groupby = df.groupby(["color", "range", "expecteddate", "vehicle"])

现在,让我们找出每个组出现最小折扣和最大日期的行:

source_idx = common_groupby["discount"].idxmin()
target_idx = common_groupby["date"].idxmax()
# Use df.loc[idx] to see the rows where the minimum discount is reached

现在,我们可以使用.loc 将最低折扣值和相应日期(来自source_idx 行)添加到正确的行(来自target_src):

df.loc[target_idx, "mindisc"] = df.loc[source_idx, "discount"].values
df.loc[target_idx, "mindate"] = df.loc[source_idx, "date"].values

如您所见,我们仅更改达到最低折扣的行中的值 (idx)。这是这些操作的输出:

   vehicle expecteddate  range color  discount       date  mindisc    mindate
0      car    2/24/2022    240  blue        70 2022-02-18     60.0 2022-02-17
1      car    2/24/2022    240   red        80 2022-02-18     40.0 2022-02-17
2      car    3/15/2022    240  blue        90 2022-02-18     50.0 2022-02-17
3      car    3/15/2022    240   red        60 2022-02-18     30.0 2022-02-17
4      car    4/20/2022    240  blue        40 2022-02-18     40.0 2022-02-18
5      car    4/20/2022    240   red        50 2022-02-18     45.0 2022-02-17
6      bus    2/24/2022    300  blue       120 2022-02-18    120.0 2022-02-18
7      bus    2/24/2022    300   red       110 2022-02-18    100.0 2022-02-17
8      bus    3/15/2022    300  blue       130 2022-02-18    130.0 2022-02-18
9      bus    3/15/2022    300   red       140 2022-02-18    120.0 2022-02-17
10     bus    4/20/2022    300  blue        80 2022-02-18     80.0 2022-02-18
11     bus    4/20/2022    300   red        90 2022-02-18     30.0 2022-02-17
12     car    2/24/2022    240  blue        60 2022-02-17      NaN        NaT
13     car    2/24/2022    240   red        40 2022-02-17      NaN        NaT
14     car    3/15/2022    240  blue        50 2022-02-17      NaN        NaT
15     car    3/15/2022    240   red        30 2022-02-17      NaN        NaT
16     car    4/20/2022    240  blue        70 2022-02-17      NaN        NaT
17     car    4/20/2022    240   red        45 2022-02-17      NaN        NaT
18     bus    2/24/2022    300  blue       130 2022-02-17      NaN        NaT
19     bus    2/24/2022    300   red       100 2022-02-17      NaN        NaT
20     bus    3/15/2022    300  blue       140 2022-02-17      NaN        NaT
21     bus    3/15/2022    300   red       120 2022-02-17      NaN        NaT
22     bus    4/20/2022    300  blue        90 2022-02-17      NaN        NaT
23     bus    4/20/2022    300   red        30 2022-02-17      NaN        NaT

另一种可能的解决方案试图通过排序然后删除重复两次来提高性能(受此问题启发:Select the max row per group - pandas performance issue):

# Min discount rows
source_df = df.sort_values(by=["discount"], ascending=True, kind='mergesort').drop_duplicates(["color", "range", "expecteddate", "vehicle"])
source_df = source_df.rename(columns={"date": "mindate", "discount": "mindisc"})

# Max date rows
target_df = df.reset_index().sort_values(by=["date"], ascending=False, kind="mergesort").drop_duplicates(["color", "range", "expecteddate", "vehicle"])

# Put min discount values into max date rows
df.loc[target_df["index"], ["mindisc", "mindate"]] = source_df[["mindisc", "mindate"]].values

【讨论】:

  • 评论不用于扩展讨论;这个对话是moved to chat
  • @aaossa @aaossa stackoverflow.com/questions/71792701/… 上面的问题链接是相同的这个问题只需要添加新列 minnegchg 和 minnegchgdate ,从 chgorders 列中找到最小负数。
  • 假设我们在列中有负值,那么如何从该列中最小或最大负值关于这个问题,比如找到最大负值和相应的最大负值日期
【解决方案2】:

我没有很好地解决问题,但您可以尝试以下方法:

new_df = df[(df['date'] == '2/18/2022') & (df['color'] == 'blue') & (df['vehicle'] == 'car')]

然后:

new_df['discount'].min()

【讨论】:

  • 考虑,车辆和预期日期 2/24/2021 和范围 240 和颜色蓝色和日期 2/18/2022,2/17/2022 并且在这个折扣列中,我们必须找到最小值并且在哪个日期最小值出现,就像我们在日期 2/18/2022,2/17/2022 有 70,60,所以最小值是 2022 年 2 月 17 日的 60 这应该添加到最新日期行的新列中特定车辆的,预期日期,范围,颜色如汽车 2/24/2022 240 蓝色 70 2/18/2022 60 2/17/2022 。这是一个预期日期,但我们应该根据上述三个预期日期检查上述相同车辆,预期,范围,颜色我希望你理解
猜你喜欢
  • 1970-01-01
  • 2022-11-10
  • 2017-12-10
  • 2021-08-22
  • 1970-01-01
  • 2018-05-01
  • 2013-05-09
  • 2019-04-02
  • 2023-03-08
相关资源
最近更新 更多