【问题标题】:Replace string value with previous row value based on conditionals - Pandas根据条件将字符串值替换为前一行值 - Pandas
【发布时间】:2019-09-21 01:34:42
【问题描述】:

鉴于满足某些条件,我正在尝试根据上一行替换当前行中的值。

条件:

当前行为 0

上一行是 C

在组内(首选,但可能没有)

类似于我的示例数据框:

ID  Week value
 4    1     W
 4    2     C
 4    3     0
 4    4     0
24    1     W
24    2     W
24    3     0
24    4     A

我需要它的外观示例:

ID  Week value
 4    1     W
 4    2     C
 4    3     C
 4    4     C
24    1     W
24    2     W
24    3     0
24    4     A

其他人提出的我似乎无法修改或不太适合我的问题的问题:

  1. conditional replace based off prior value in same column of pandas dataframe python
  2. conditional change of a pandas row, with the previous row value

构建类似于我的数据框的代码

import pandas as pd

df = pd.DataFrame({'ID': {0:'4', 1:'4', 2:'4', 3:'4', 4:'24', 5:'24', 6:'24', 7:'24'}, 'Week': {0:'1', 1:'2', 2:'3', 3:'4', 4: '1', 5:'2', 6:'3', 7:'4'},  'value': {0:'W', 1:'C', 2:'0', 3:'0', 4: 'W', 5:'W', 6:'0', 7:'A'} })
df[['ID', 'Week']] = df[['ID', 'Week']].astype('int')

解决问题的尝试效果不佳(引发错误)

for i in range(1, len(df)):
    if df.value[i] == '0' and df.value[i-1] == 'C':
         df.value[i] = 'C'
     else:
         df.value[i] = df.value[i]

【问题讨论】:

    标签: python pandas numpy dataframe


    【解决方案1】:

    通常,我会使用np.where 将条件应用于列。但是,鉴于 .shift() 函数,如果不将其放入 for 循环中,这将不起作用。一个快速的方法是使用.replace()

    for row in range(0,len(df)):
        df['value'] = df['value'].replace('0',df['value'].shift(1))
    

    如果您希望保持有条件,您仍然可以以类似的方式使用np.where

    for row in range(0,len(df)):
        df['value'] = np.where((df['value'] == '0') & (df['value'].shift(1) == 'C'), 'C', df['value'])
    

    【讨论】:

    • 不错的答案,得到了几乎相同的结果,但循环抛出了我,我试图想一个矢量化的解决方案,但没有雪茄。
    • 按 ID 分组时可以这样做吗?
    • 由于当前数据结构而有效,但可能存在我必须按 ID 分组的情况
    • 我添加了 df['ID'].shift() == df['ID'] 以确保在分组之外不会发生替换
    【解决方案2】:

    不容易推广到其他情况,但对于您的具体情况,您可以这样做:

    is_0 = df['value'] == '0'
    is_C_block = df['value'].replace('0', pd.np.nan).fillna(method='ffill') == 'C'
    
    df.loc[is_0 & is_C_block, 'value'] = 'C'
    

    【讨论】:

    • 按 ID 分组时可以这样做吗?
    • 由于当前的数据结构而有效,但可能存在我必须按 ID 分组的情况
    • 分组会做什么?一些不同的替代品?
    • 防止在分组之外引用替换。即,如果个体 24 的第一个值为 0,则防止替换个体 4 的第一个值,如果个体 4 的最后一个值为 c
    • 您可以使用 df['ID'].shift() != df['ID'] 在新 ID 开始时包含额外条件...
    猜你喜欢
    • 2023-03-08
    • 2021-11-27
    • 1970-01-01
    • 2018-09-26
    • 1970-01-01
    • 2018-12-05
    • 2015-06-27
    • 2020-08-11
    • 2021-07-19
    相关资源
    最近更新 更多