【问题标题】:How to apply a condition to Pandas dataframe rows, but only apply the condition to rows of the same day?如何将条件应用于 Pandas 数据框行,但仅将条件应用于同一天的行?
【发布时间】:2021-10-08 11:33:05
【问题描述】:

我有一个按日期时间索引的数据框,并且有一列整数和另一列,如果满足整数条件,我想将其放入字符串中。我需要条件来评估 X 行中的整数与 X-1 行中的整数,但前提是两行都在同一天。

我目前正在使用条件:

df.loc[(df['IntCol'] > df['IntCol'].shift(periods=1)), 'StringCol'] = 'Success'

这成功地应用了我的条件,但是如果移动的行在不同的日期,那么条件仍然会使用它,我希望它忽略在不同日期的任何行。我尝试了groupby(df.index.date) 的各种迭代,但似乎无法确定这是否可行。

【问题讨论】:

  • 请发布示例数据框。

标签: python pandas dataframe


【解决方案1】:

不确定这是否是最好的方法,但可以为您提供答案:

df['out'] = np.where(df['int_col'] > df.groupby(df.index)['int_col'].shift(1), 'Success', 'Failure') 

【讨论】:

  • 我认为你需要使用 df.index.date
  • 绝对更简洁,使用 np 比 apply() 方法更快。 EBDS 提到需要 .date
  • 添加 .date 后这对我有用。我之前尝试过 np.where 函数,但我试图在条件的两边都使用 df.groupby 。为什么 df.groupby 仅在 shift(1) 条件的一侧出现?我原以为代码会通过处理两个不同的数据集,而您必须在整个条件下使用 groupby。
  • 本文在#6中有详细解释:towardsdatascience.com/…
【解决方案2】:

我想这就是你想要的。你可能比你想象的更接近答案......

有两个数据框用于表明您的逻辑是否有效,无论数据是随机的还是整数是排序范围的。

你需要随机导入才能看到数据

dates = list(pd.date_range(start='2021/1/1', periods=16, freq='4H'))

def compare(x):
    x.loc[(x['IntCol'] > x['IntCol'].shift(periods=1)), 'StringCol'] = 'Success'
    return x

#### Will show success in all rows except where dates change because it's a range in numerical order
df = pd.DataFrame({'IntCol': range(10,26)}, index=dates)
df.groupby(df.index.date).apply(compare)

2021-01-01 00:00:00      10       NaN
2021-01-01 04:00:00      11   Success
2021-01-01 08:00:00      12   Success
2021-01-01 12:00:00      13   Success
2021-01-01 16:00:00      14   Success
2021-01-01 20:00:00      15   Success
2021-01-02 00:00:00      16       NaN
2021-01-02 04:00:00      17   Success
2021-01-02 08:00:00      18   Success
2021-01-02 12:00:00      19   Success
2021-01-02 16:00:00      20   Success
2021-01-02 20:00:00      21   Success
2021-01-03 00:00:00      22       NaN
2021-01-03 04:00:00      23   Success
2021-01-03 08:00:00      24   Success
2021-01-03 12:00:00      25   Success

### random numbers to show that it works here too
df = pd.DataFrame({'IntCol':  [random.randint(3, 500) for x in range(0,16)]}, index=dates)
df.groupby(df.index.date).apply(compare)

                     IntCol StringCol
2021-01-01 00:00:00     386       NaN
2021-01-01 04:00:00     276       NaN
2021-01-01 08:00:00     143       NaN
2021-01-01 12:00:00     144   Success
2021-01-01 16:00:00      10       NaN
2021-01-01 20:00:00     343   Success
2021-01-02 00:00:00     424       NaN
2021-01-02 04:00:00     362       NaN
2021-01-02 08:00:00     269       NaN
2021-01-02 12:00:00      35       NaN
2021-01-02 16:00:00     278   Success
2021-01-02 20:00:00     268       NaN
2021-01-03 00:00:00      58       NaN
2021-01-03 04:00:00     169   Success
2021-01-03 08:00:00      85       NaN
2021-01-03 12:00:00     491   Success

【讨论】:

  • 你说得对,我在几个方面都非常接近,但只是语法不太正确。现在奇怪的是,当与 groupby 一起使用时,条件永远不会为真。我基本上有确切的场景作为你的随机数示例,但我没有得到相同的输出,事实上,如果我使用与你相同的示例数据帧,那么我仍然没有得到真实的条件。如何复制确切的代码并获得不同的结果?
  • 不确定为什么你会得到不同的结果,但你可以使用 Poorval Dhotre 的答案,因为它也有效,而且它是更快的解决方案。
猜你喜欢
  • 1970-01-01
  • 2021-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-19
  • 2021-06-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多