【问题标题】:Add 1/0 to Pandas cel if in-between dates condition for tuple element in list is met如果满足列表中元组元素的中间日期条件,则将 1/0 添加到 Pandas cel
【发布时间】:2017-10-09 14:38:18
【问题描述】:

如果 ipu 中的任何日期介于 Date_range 中的日期范围之间,我正在寻找在 InRange 单元格中添加 1,否则为 0。

元组列表:

ipu = [('2016-05-31', '5,000'),('2015-03-06', '2,920')]

df:

          Date                Date_range  InRange
0   2016-07-26  [2016-07-26, 2016-04-26]      NaN
1   2016-04-26  [2016-04-26, 2016-01-26]      NaN
2   2016-01-26  [2016-01-26, 2015-10-27]      NaN
3   2015-10-27  [2015-10-27, 2015-07-21]      NaN
4   2015-07-21  [2015-07-21, 2015-04-27]      NaN
5   2015-04-27  [2015-04-27, 2015-01-27]      NaN
6   2015-01-27  [2015-01-27, 2014-10-20]      NaN
7   2014-10-20  [2014-10-20, 2014-07-22]      NaN
8   2014-07-22  [2014-07-22, 2014-04-23]      NaN
9   2014-04-23  [2014-04-23, 2014-01-27]      NaN
10  2014-01-27  [2014-01-27, 2013-10-28]      NaN
11  2013-10-28  [2013-10-28, 2013-07-23]      NaN
12  2013-07-23                       NaN      NaN

期望的输出:

          Date                Date_range  InRange
0   2016-07-26  [2016-07-26, 2016-04-26]      1
1   2016-04-26  [2016-04-26, 2016-01-26]      0
2   2016-01-26  [2016-01-26, 2015-10-27]      0
3   2015-10-27  [2015-10-27, 2015-07-21]      0
4   2015-07-21  [2015-07-21, 2015-04-27]      0
5   2015-04-27  [2015-04-27, 2015-01-27]      1
6   2015-01-27  [2015-01-27, 2014-10-20]      0
7   2014-10-20  [2014-10-20, 2014-07-22]      0
8   2014-07-22  [2014-07-22, 2014-04-23]      0
9   2014-04-23  [2014-04-23, 2014-01-27]      0
10  2014-01-27  [2014-01-27, 2013-10-28]      0
11  2013-10-28  [2013-10-28, 2013-07-23]      0
12  2013-07-23                       NaN      0

这是我尝试过的代码:

for i in range(len(df.index)-1):
    for r in range(len(ipu)):
        df.loc[(df['Date_range'][i][0] > ipu[r][0]) & (df['Date_range'][i][1] <= ipu[r]), 'InRange'[i]] = 1

我得到:

KeyError: 'cannot use a single bool to index into setitem'

我看了

KeyError when using boolean filter on pandas data frame

但不清楚如何将其应用于我的案例。

我知道我的代码已经完成了一半,但我被卡住了......我很欣赏一些指导。

谢谢

【问题讨论】:

  • 你的循环中的i是什么?
  • @IanS,我使用 i 添加了 for 循环行。
  • 在基本级别上,您只能索引具有相同长度的布尔向量的数据帧。在这里,您的表达式返回一个布尔值(TrueFalse),因此索引失败。
  • 谢谢@IanS。我应该寻找什么类型的解决方案?
  • @IanS 我尝试使用日期范围作为列表,并为日期元组应用 for 循环和 for 循环,但也没有成功(并且认为它的计算效率非常低)

标签: python-2.7 pandas boolean


【解决方案1】:

将列表作为列中的值通常是个坏主意。将pd.Series 应用于Date_range 以制作正确的数据框,然后使用该结果检查ipu 中的每个日期。

df_dates = df['Date_range'].apply(lambda x: pd.Series(x, index=['end', 'start']))

          end      start
0  2016-07-26 2016-04-26
1  2016-04-26 2016-01-26
2  2016-01-26 2015-10-27
3  2015-10-27 2015-07-21
4  2015-07-21 2015-04-27
5  2015-04-27 2015-01-27
6  2015-01-27 2014-10-20
7  2014-10-20 2014-07-22
8  2014-07-22 2014-04-23
9  2014-04-23 2014-01-27
10 2014-01-27 2013-10-28
11 2013-10-28 2013-07-23
12        NaT        NaT

dates = pd.to_datetime([d[0] for d in ipu])
sum([(d >= df_dates.start) & (d <= df_dates.end) for d in dates]).gt(0).astype(int)

0     1
1     0
2     0
3     0
4     0
5     1
6     0
7     0
8     0
9     0
10    0
11    0
12    0
dtype: int64

【讨论】:

    猜你喜欢
    • 2021-08-26
    • 1970-01-01
    • 1970-01-01
    • 2014-05-22
    • 1970-01-01
    • 2019-01-17
    • 2020-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多