在多列上强加层次结构,基于其他列更改列值的随机数

时间:2019-07-12 11:29:39

标签: python pandas numpy

我有一个数据集,其中包含客户的ID以及名为“ WEEK1”,“ WEEK2”等的指标。如果在该特定星期登记了客户,则值= 1,否则为0,如下所示:

ID WEEK1 WEEK2 WEEK3 WEEK4 WEEK5
1   0     0     1     0     1
2   0     0     0     0     1
3   1     0     1     0     1
4   0     0     0     0     0
5   1     1     1     1     1
6   1     0     0     0     0
7   0     1     1     1     0

我想做的是搜索客户注册的第一周,保持该周的指标= 1,然后将该客户ID的所有其他周指标值更改为0,即O / P:-

ID WEEK1 WEEK2 WEEK3 WEEK4 WEEK5
1   0     0     1     0     0  ## WEEK5 is changed to 0 here
2   0     0     0     0     1  ## nothing changed
3   1     0     0     0     0  ## WEEK3 and WEEK5 is changed to 0
4   0     0     0     0     0
5   1     0     0     0     0
6   1     0     0     0     0
7   0     1     0     0     0

因此,对于每个客户ID,我们找到第一个WEEK,其值= 1,然后将所有下一个WEEK值= 0。

现在我已经使用if-else尝试过,将每个条件一个一个地放置,如下所示:

if df['WEEK1'] == 1:
    df['WEEK2'] = 0
    df['WEEK3'] = 0
    df['WEEK4'] = 0
    df['WEEK5'] = 0
elif df['WEEK2'] == 1:
    df['WEEK3'] = 0
    df['WEEK4'] = 0
    df['WEEK5'] = 0
... and so on

当只有5个WEEK列时,使用if-else对我有用,但是现在我获得了52个WEEK列的数据,除了使用if-else之外,我找不到其他选择。

因此,任何适用于在这5列上强加层次结构并且还可以扩展到可变数量的列(如52、104等)的东西都会很有帮助。

1 个答案:

答案 0 :(得分:3)

使用:

#if first column is not index
df = df.set_index('ID')
df = df.where(df.shift(axis=1).eq(1).cumsum(axis=1).eq(0), 0)
print (df)
    WEEK1  WEEK2  WEEK3  WEEK4  WEEK5
ID                                   
1       0      0      1      0      0
2       0      0      0      0      1
3       1      0      0      0      0
4       0      0      0      0      0
5       1      0      0      0      0
6       1      0      0      0      0
7       0      1      0      0      0

详细信息和说明

第一个DataFrame.shift右边的值:

print (df.shift(axis=1))
    WEEK1  WEEK2  WEEK3  WEEK4  WEEK5
ID                                   
1     NaN    0.0    0.0    1.0    0.0
2     NaN    0.0    0.0    0.0    0.0
3     NaN    1.0    0.0    1.0    0.0
4     NaN    0.0    0.0    0.0    0.0
5     NaN    1.0    1.0    1.0    1.0
6     NaN    1.0    0.0    0.0    0.0
7     NaN    0.0    1.0    1.0    1.0

如果可能,用1比较另一个值,例如10,否则省略此步骤:

print (df.shift(axis=1).eq(1))
    WEEK1  WEEK2  WEEK3  WEEK4  WEEK5
ID                                   
1   False  False  False   True  False
2   False  False  False  False  False
3   False   True  False   True  False
4   False  False  False  False  False
5   False   True   True   True   True
6   False   True  False  False  False
7   False  False   True   True   True

通过DataFrame.cumsum获取每行的累积总和:

print (df.shift(axis=1).eq(1).cumsum(axis=1))
    WEEK1  WEEK2  WEEK3  WEEK4  WEEK5
ID                                   
1       0      0      0      1      1
2       0      0      0      0      0
3       0      1      1      2      2
4       0      0      0      0      0
5       0      1      2      3      4
6       0      1      1      1      1
7       0      0      1      2      3

0比较:

print (df.shift(axis=1).eq(1).cumsum(axis=1).eq(0))
    WEEK1  WEEK2  WEEK3  WEEK4  WEEK5
ID                                   
1    True   True   True  False  False
2    True   True   True   True   True
3    True  False  False  False  False
4    True   True   True   True   True
5    True  False  False  False  False
6    True  False  False  False  False
7    True   True  False  False  False

上次由掩码False设置为DataFrame.where0的值:

print (df.where(df.shift(axis=1).eq(1).cumsum(axis=1).eq(0), 0))
    WEEK1  WEEK2  WEEK3  WEEK4  WEEK5
ID                                   
1       0      0      1      0      0
2       0      0      0      0      1
3       1      0      0      0      0
4       0      0      0      0      0
5       1      0      0      0      0
6       1      0      0      0      0
7       0      1      0      0      0