python - 有条件地创建(填充)一列,该列必须处理数据框中的行以匹配条件

标签 python pandas dataframe

我有一个数据框,其中有几个日期时间值列和一些其他分类/连续列。 为了便于描述,我上传了数据帧的片段,还删除了实际日期值以避免困惑。

enter image description here

我正在尝试创建一个列,该列必须处理数据框中的行以匹配条件,然后才能决定在这个新列中填充什么内容。

在这种情况下:

如果某行的 SECTOR AND BASE 值与其他行中的相同值匹配 和 如果此/这些前行(具有 SECTOR AND BASE 的行等于现在发现具有相同 SECTOR AND BASE 的行)行的结束日期与数据帧中稍后阶段的行的 START 日期匹配,然后填充 1,否则填充 0。 所以,本质上,我正在考虑这样的事情:

enter image description here

 BASE     SECTOR     START    END     CHECK
 S     DHHJJ    12/2/2018   13/3/2018   0
 B       DJH    12/3/2018   13/3/2018   0
 S      FHJDFJK 12/4/2018   13/3/2020   0
 B     FHJDG    12/5/2018   13/3/2021   0
 T       XYZ    23/03/2018  25/03/2018  1
 T      ABCD    12/1/2017   13/2/2017   0
 T      ABCD    1/2/2018    1/3/2018    1
 T      ABCD    1/3/2018    15/3/2018   1
 T       XYZ    12/1/2015   12/2/2015   0
 B       XYZ    15/5/2017   15/7/2017   1
 T       XYZ    12/2/2014   12/3/2014   0
 B       XYZ    15/7/2017   20/7/2017   0
 T     SFJUTEUI 12/2/2018   13/3/2018   0
 T      RUTI    12/3/2018   13/3/2019   0
 T      FDJTK   12/4/2018   13/3/2020   0
 B    FJURTUI   12/5/2018   13/3/2021   0
 T    RYURTI    12/6/2018   13/3/2022   0
 T     SFJUI    12/7/2018   13/3/2023   0
 T       XYZ    25/03/2018  30/03/2018  0
 T       XYZ    12/4/2018   12/4/2018   0
 T       XYZ    1/4/2016    1/5/2016    1
 T       XYZ    1/5/2016    5/5/2016    0
 T      ABCD    15/3/2018   31/3/2018   0

添加独家修改BASE条件的数据:

BASE    SECTOR  START       END       CHECK
   S    DHHJJ   12/2/2018   13/3/2018   0
   B    DJH    12/3/2018    13/3/2018   0
   S    FHJDFJK 12/4/2018   13/3/2020   0
   B    FHJDG   12/5/2018   13/3/2021   0
   T    XYZ 23/03/2018  25/03/2018  1
   T    ABCD    12/1/2017   13/2/2017   0
   B    ABCD    1/2/2018    1/3/2018    1
   T    ABCD    1/3/2018    15/3/2018   1
   T    XYZ    12/1/2015    12/2/2015   0
   B    XYZ    15/5/2017    15/7/2017   1
   T    XYZ    12/2/2014    12/3/2014   0
   T    XYZ    15/7/2017    20/7/2017   0
   T    SFJUTEUI    12/2/2018   13/3/2018   0
   T    RUTI    12/3/2018   13/3/2019   0
   T    FDJTK   12/4/2018   13/3/2020   0
   B    FJURTUI 12/5/2018   13/3/2021   0
   T    RYURTI  12/6/2018   13/3/2022   0
   T    SFJUI   12/7/2018   13/3/2023   0
   T    XYZ   25/03/2018    30/03/2018  0
   T    XYZ    12/4/2018    12/4/2018   0
   T    XYZ     1/4/2016    1/5/2016    1
   B    XYZ     1/5/2016    5/5/2016    0
   B    ABCD    15/3/2018   31/3/2018   0

最佳答案

使用带有 groupby 的自定义函数来检查成员资格并排除具有相同 STARTEND 日期的行。对于 0, 1 值,将 bool 值转换为整数。

df[['START','END']] = df[['START','END']].apply(pd.to_datetime)

def f(x):
    #test all start datetimes, order is not important
    x['Check1'] = (x['END'].isin(x['START']) & (x['END'] != x['START'])).astype(int)
    return x

df = df.groupby(['BASE','SECTOR']).apply(f)
print (df)
   BASE    SECTOR      START        END  CHECK  Check1
0     S     DHHJJ 2018-12-02 2018-03-13      0       0
1     B       DJH 2018-12-03 2018-03-13      0       0
2     S   FHJDFJK 2018-12-04 2020-03-13      0       0
3     B     FHJDG 2018-12-05 2021-03-13      0       0
4     T       XYZ 2018-03-23 2018-03-25      1       1
5     T      ABCD 2017-12-01 2017-02-13      0       0
6     T      ABCD 2018-01-02 2018-01-03      1       1
7     T      ABCD 2018-01-03 2018-03-15      1       1
8     T       XYZ 2015-12-01 2015-12-02      0       0
9     B       XYZ 2017-05-15 2017-07-15      1       1
10    T       XYZ 2014-12-02 2014-12-03      0       0
11    B       XYZ 2017-07-15 2017-07-20      0       0
12    T  SFJUTEUI 2018-12-02 2018-03-13      0       0
13    T      RUTI 2018-12-03 2019-03-13      0       0
14    T     FDJTK 2018-12-04 2020-03-13      0       0
15    B   FJURTUI 2018-12-05 2021-03-13      0       0
16    T    RYURTI 2018-12-06 2022-03-13      0       0
17    T     SFJUI 2018-12-07 2023-03-13      0       0
18    T       XYZ 2018-03-25 2018-03-30      0       0
19    T       XYZ 2018-12-04 2018-12-04      0       0
20    T       XYZ 2016-01-04 2016-01-05      1       1
21    T       XYZ 2016-01-05 2016-05-05      0       0
22    T      ABCD 2018-03-15 2018-03-31      0       0

如果日期时间的排序对于检查成员资格很重要:

def f1(x):
    e = x['END']
    s = x['START']
    #for each start datetime test all next end datetimes
    m = {j[0]: (s.iloc[i+1:] == j[1]).any() for i,j in enumerate(e.items())}
    x['Check2'] = pd.Series(m).astype(int)
    return x

df = df.groupby(['BASE','SECTOR']).apply(f1)
print (df)

为了更好地查看差异,更改了一个值:

print (df.tail())
   BASE SECTOR       START         END  CHECK
18    T    XYZ  25/03/2018  30/03/2018      0
19    T    XYZ    5/5/2016   12/4/2018      0 <-changed value to 5/5/2016
20    T    XYZ    1/4/2016    1/5/2016      1
21    T    XYZ    1/5/2016    5/5/2016      0
22    T   ABCD   15/3/2018   31/3/2018      0


df = df.groupby(['BASE','SECTOR']).apply(f)
df = df.groupby(['BASE','SECTOR']).apply(f1)
print (df.tail())
   BASE SECTOR      START        END  CHECK  Check1  Check2
18    T    XYZ 2018-03-25 2018-03-30      0       0       0
19    T    XYZ 2016-05-05 2018-12-04      0       0       0
20    T    XYZ 2016-01-04 2016-01-05      1       1       1
21    T    XYZ 2016-01-05 2016-05-05      0       1       0
22    T   ABCD 2018-03-15 2018-03-31      0       0       0

关于python - 有条件地创建(填充)一列,该列必须处理数据框中的行以匹配条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49686189/

相关文章:

python - 如何使用 pandas 更改列值和排序?

r - 将数据框的名称提取为 R tidyverse 中的字符串

python - Matplotlib 简单的不同颜色线条图

python - 如何使用 Python 加入两个视频文件?

python - 从日期列表中删除单词 DateTimeIndex

python - 每当超过某个 cumsum 阈值时如何对 pandas 行进行分组(为每个新组重新启动 cumsum)

python - 多行为空时如何进行合并

python - 在python中调用shell命令

python - matplotlib pyplot.plot() : How do you plot data as a line when the data contains a single value surrounded by masks?

python - 合并字典中的数据框