如果满足某些条件,如何翻转列

时间:2020-02-06 00:07:26

标签: python pandas

我对熊猫有疑问。 假设我有下表

| condition |  value |
|-----------|--------|
| Yes       |  0     |
|-----------|--------|
| Yes       |  1     |
|-----------|--------|
| Yes       |  2     |
|-----------|--------|
| Yes       |  3     |
|-----------|--------|
| Yes       |  4     |
|-----------|--------|
| No        |  0     |
|-----------|--------|
| Yes       |  4     |
|-----------|--------|
| Yes       |  5     |
|-----------|--------|
| Yes       |  6     |
|-----------|--------|
| No        |  0     |
|-----------|--------|

我想得到以下关注

| condition |  value |
|-----------|--------|
| Yes       |  4     |
|-----------|--------|
| Yes       |  3     |
|-----------|--------|
| Yes       |  2     |
|-----------|--------|
| Yes       |  1     |
|-----------|--------|
| Yes       |  0     |
|-----------|--------|
| No        |        |
|-----------|--------|
| Yes       |  2     |
|-----------|--------|
| Yes       |  1     |
|-----------|--------|
| Yes       |  0     |
|-----------|--------|
| No        |        |
|-----------|--------|

为此,尽管我可以做循环以获得类似结果:

continue_condition = False
for index, row in df.iterrows():
    if row['condition'] == 'Yes': 
       if not continue_condition:
           continue_condition = True
           min_value = row['value']

    else:
       continue_condition = False
       max_value = row['value']
       start_point = max_value - min_value
       point_value = 0
       while point_value <= start_point:
           df.loc[index-point_value, "new_value"] = point_value
           point_value += 1
        min_value = None
        max_value = None
        point_value = None

但是,这是慢速代码,只是想知道我是否可以加快代码速度?

1 个答案:

答案 0 :(得分:1)

这是一种解决方案:

 condition = [('Yes',0),('Yes',1), ('Yes',2), ('Yes',3),('Yes',4),('No',0),('Yes',4),('Yes',5),('Yes',6),('No',0)]

 df = pd.DataFrame(condition,columns=['condition','value'])

numpy flip“翻转”数组

(pd
 .DataFrame(np.flip(df.to_numpy(),1), 
            columns=['value','condition'])

 #create helper columns 

 .assign(check = lambda x: x.value.diff(-1),
         temp = lambda x: np.where(x.check.abs() > 1, 
                                   x.check.abs(),np.nan)
        )
 .assign(temp = lambda x: x.temp.fillna(method = 'bfill'),
         value = lambda x: np.where(x.condition=="Yes",
                                    x.value.sub(x.temp).abs(),"")
         )
 .filter(['condition','value'])
  )


  condition value
0   Yes 4
1   Yes 3
2   Yes 2
3   Yes 1
4   Yes 0
5   No  
6   Yes 2
7   Yes 1
8   Yes 0
9   No