【问题标题】:Conditional row iterating in Pandas to create new featurePandas 中的条件行迭代以创建新功能
【发布时间】:2020-03-15 09:43:47
【问题描述】:

我有这样一个例子的数据:

df11 = pd.DataFrame({'code': [33000000, 33230000, 33235600, 33235678, 17000000,17980000],
                 'Name': ['txt1','txt2','txt3','txt4','txt5','txt6'],
                'level': [1,2,3,4,3,4]})
print(df11)

我的目标是遍历行(实际上大约 100,000 行)并仅在级别 ==4 时创建一个由名称组合的新功能。所以最终输出应该是这样的:

code       combined_names
33235678   txt1+txt2+txt3+txt4
17980000   txt5+txt6

8 位代码始终与级别相关联,级别 1 的代码始终为例如 33000000,然后为级别 2 添加另外 2 个数字,例如 33230000 等等。代码可能在数据框中的任何地方,不一定是连续的行,但总是使用这种逻辑。

我已经完成了以下操作,直到第一次出现条件 level=4(检查将 2nd level=4 替换为例如 9)。但实际上有更多的条件级别=4,我得到以下错误:

def combined_names(code):
    code_list=[(code-code%10**x) for x in [6,4,2,0]]

    #above I obtain the codes correspond to level 1 to level4 when level=4 is 
    #satisfied, by difference and modulo operator to 10**6, 
    #10**4,10**2,1. e.g For 33235678 as input we get: 
    #33000000,33230000,33235600 and 33235678   

    print(code_list)
    name1=df11.query('code == @code_list[0]')['Name'].tolist()
    name2=df11.query('code == @code_list[1]')['Name'].tolist()
    name3=df11.query('code == @code_list[2]')['Name'].tolist()
    name4=df11.query('code == @code_list[3]')['Name'].tolist()

    name_list=name1+name2+name3+name4
    print(name_list)

    all_names= ' + '.join(name_list)
    return all_names
combined_names(33235678)

conditions = [df11['level'] == 4]
choices = [combined_names( df11.query('level==4')['code'].item() )] 
# problem: if there are more than one level4, then it does NOT iterate over.

# CHECK : https://stackoverflow.com/questions/16476924/how-to-iterate-over-rows-in-a-dataframe-in-pandas

df11['all_names'] = np.select(conditions, choices, default='NaN')
print(df11) 

ValueError: can only convert an array of size 1 to a Python scalar

如何修改函数以在 df 中捕获所有需要的条件?一般来说,执行此任务的更优化方法是什么?谢谢!

【问题讨论】:

  • 我想你只是想提取那些符合你条件的组合值的行?

标签: python pandas dataframe iteration rows


【解决方案1】:

创建一个临时列来检查级别是否为 4

df11['level_4'] = df11.loc[df11['level']==4,'Name']

向后填充以与前一行关联

df11 = df11.bfill()

在 level_4 上分组并使用 string cat 聚合

M = df11.groupby('level_4').Name.agg(lambda x: x.str.cat(sep='+'))
M = M.rename('combined_names')

合并回原始数据框

     (df11[['code','Name']]
      .merge(M,left_on='Name',right_on='level_4')
      .drop('Name',axis=1)
      )

    code    combined_names
0   33235678    txt1+txt2+txt3+txt4
1   17980000    txt5+txt6

【讨论】:

  • 谢谢。太好了,不知道 bfill(),但实际上并不总是用之前的行来填充它。逻辑是在我编写的 code_list 中搜索该模式。我可以加入吗?
  • 如果可以,请编辑您的原始问题,并包含对您的代码的解释,以便其他人也可以贡献。
  • 我添加了更多信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-19
  • 1970-01-01
  • 2022-01-19
  • 2019-04-27
  • 2020-09-30
  • 1970-01-01
相关资源
最近更新 更多