首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何根据Python中的某些条件将当前行与前2行进行比较

如何根据Python中的某些条件将当前行与前2行进行比较
EN

Stack Overflow用户
提问于 2022-03-19 00:56:52
回答 3查看 220关注 0票数 0

我有一个类似于下面的数据集,我想根据以下条件比较每一个库存项目的所有行

如果“

  1. ”列为非空,则将其标记为"yes"

如果所有行(每个库存)的“”列为空,则对“

  1. ”列计算"item“列,如果"item”列不为空,则应将该行标记为“是”。或"value“下的1条记录为空,其中"value”下的2条记录不为空,则这2行需要根据项

进行计算。

如果"value“和"item”都为null(每个库存),则

  1. 对“年份”列进行评估,并标记最新的年份"yes“。或"value“为null,但"item”下的1条记录为null,其中"item“下的2条记录不为空,然后计算”年份“列并标记更新最多的年份"yes"

  1. df'flag'.fillna('no',inplace=True)

我可以设置这个,如果是logic逻辑,但我不知道如何将当前行与前两个行进行比较。具有转换和自定义功能的groupby是很好的建议,我想知道如何捕捉所有这些场景,或者是否有更好的方法。

下面是简化的df的样子。在我的真实数据集中,正如上面所描述的,对于相同的库存,"value“列都是空的,但是在"item”不是null下有2行,在这种情况下,需要为这2行计算“年份”列。

代码语言:javascript
运行
复制
df1 = { 'inventory':['inv1','inv1','inv1','inv2','inv2','inv2','inv3','inv3','inv3'],
  'value':['xyz','','','','','','','',''],
  'item':['','304','304','','205','','','',''],
   'year':[2020,2020,2020,2020,2020,2020,2019,2018,2020]}

df1=pd.DataFrame(df1)

所需的输出如下所示--根据上述多个条件向标志'yes'/'no‘添加一个标志列。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2022-03-19 19:14:58

通过借用“Peter Leimbigler”和“richardec”的思想,我修改了下面的逻辑,它适用于我的实际工作情况(这比我在问题中提出的要复杂得多),因为每个库存项目有不同的行数,“值”、“项目”和“年份”的组合也不同。

我的解决方案唯一的缺点是我不能使用groupby,所以我必须创建一个循环来为每个库存项目创建单独的df,并将它们附加到一个完整的数据框架中。我希望有更好的办法。

代码语言:javascript
运行
复制
df1 = df1.replace('', np.nan)

def make_flag_col(df,n):
    comment_len = len(df.loc[df['value'].notna(),:])
    jus_len = len(df.loc[df['item'].notna(),:])
    maxi = df['year'].max()
    n = df.shape[0]
    if comment_len == 1:
        df.loc[df['value'].notna(),'flag'] = 'keep'
    elif comment_len >=2 or comment_len == 0:
        if jus_len == 1:
            df.loc[df['item'].notna(),'flag'] = 'keep'
        else:
            df.loc[df['year']==maxi,'flag'] = 'keep'
    else:
        print('out of pattern, check')
        return df

l = df1['inventory'].unique().tolist()

full_df = []
for itm in l:
    df_test = df1[df1['inventory']== itm].copy()
    df_test = df_test.sort_values(by=['year']).reset_index()
    df_row_number = df_test.shape[0]

    make_flag_col(df_test,df_row_number - 1)

    for i in range(len(df_test)):
        row = df_test.iloc[i]
        whole = list(row)
        full_df.append(whole)

full_df = pd.DataFrame(full_df,columns=list(df_test.columns))
full_df['flag'].fillna('remove',inplace=True)
票数 0
EN

Stack Overflow用户

发布于 2022-03-19 01:13:38

这其实不是很复杂。您通常需要几个groupby + transform组合。下面是一个矢量化(阅读:非常快)的解决方案:

代码语言:javascript
运行
复制
df = df.replace('', np.nan)

cond = (
    df['value'].notna() |
        (df['value'].isna().groupby(df['inventory']).transform('all') 
            & df['item'].notna()) |
        (df[['value', 'item']].isna().groupby(df['inventory']).transform('all').all(axis=1) &
            (df['year'] == df.groupby('inventory')['year'].transform('max')))
)

df['flag'] = cond.map({True: 'yes', False: 'no'})

输出:

代码语言:javascript
运行
复制
>>> df
  inventory value item  year flag
0      inv1   xyz  NaN  2020  yes
1      inv1   NaN  304  2020   no
2      inv1   NaN  304  2020   no
3      inv2   NaN  NaN  2020   no
4      inv2   NaN  205  2020  yes
5      inv2   NaN  NaN  2020   no
6      inv3   NaN  NaN  2019   no
7      inv3   NaN  NaN  2018   no
8      inv3   NaN  NaN  2020  yes
票数 1
EN

Stack Overflow用户

发布于 2022-03-19 01:18:08

您可以将规则写入自定义函数,并将其应用于每个组:

代码语言:javascript
运行
复制
# Replace blank spaces with NaN
df1 = df1.replace('', np.nan)

def make_flag_col(subdf):
    if subdf['value'].any():
        return subdf['value'].notna()
    elif subdf['item'].any():
        return subdf['item'].notna()
    else:
        return subdf['year'] == subdf['year'].max()

df1['flag'] = (df1.groupby('inventory', group_keys=False)
                  .apply(make_flag_col)
                  .replace({True: 'yes', False: 'no'}))

print(df1)

  inventory value item  year flag
0      inv1   xyz  NaN  2020  yes
1      inv1   NaN  304  2020   no
2      inv1   NaN  304  2020   no
3      inv2   NaN  NaN  2020   no
4      inv2   NaN  205  2020  yes
5      inv2   NaN  NaN  2020   no
6      inv3   NaN  NaN  2019   no
7      inv3   NaN  NaN  2018   no
8      inv3   NaN  NaN  2020  yes
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71534576

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档