【问题标题】:Lambda + Apply to get two new columns in PandasLambda + Apply 在 Pandas 中获取两个新列
【发布时间】:2018-12-03 12:24:07
【问题描述】:

我的 df 看起来像:

Name                 Item
A,D,B,B,C,C      I1,I2,I3,I1,I2
X,Y,Z,Z,Z            I4,I1,I1,I88,I4 

预期输出:

Name            Item         Unique_Name  Unique_Item Count_Unique_name  Count_Unique_Item
A,D,B,B,C,C  I1,I2,I3,I1,I2    A,B,C,D      I1,I2,I3         4             3             
X,Y,Z,Z,Z   I4,I1,I1,I88,I4    X,Y,Z       I4,I1,I88         3             4

代码:

new_items_df['Unique_Name'] = new_items_df['Name'].apply(lambda x: set(x.lower().split(",")))
new_items_df['Unique_Item'] = new_items_df['Item'].apply(lambda x: set(x.lower().split(",")))
new_items_df['Count_Unique_Name'] = new_items_df['Unique_Modifier'].apply(lambda x: len(x))
new_items_df['Count_Unique_Item'] = new_items_df['Unique_Item'].apply(lambda x: len(x))

上面的代码工作正常,但我正在执行相同的操作并运行相同的代码两次。当我尝试合并第一两行代码时,如下所示:

new_items_df[['Unique_Name','Unique_Item']] = new_items_df[['Name','Item']].apply(lambda x: set(x.str.lower().str.split(",")),axis =1)

TypeError: ("unhashable type: 'list'", '发生在索引 0')

我尝试使用 .unique()also,尝试使用 [] 将其转换为列表,但似乎没有任何效果,我遇到了一个或另一个错误

总结:

那么,我可以将我的 4 行代码合并为 1 行吗?

【问题讨论】:

  • D 是如何输出的?
  • 是的,现在编辑了
  • 我认为您可以在 apply 中删除axis =1
  • 为这样的操作编写一个函数总是更好。

标签: python pandas lambda apply


【解决方案1】:

您可以使用applymap 处理标量:

c = ['Name','Item']
#python 3.6+ solution
c1 = [f'Unique_{x}' for x in c]
c2 = [f'Count_Unique_{x}' for x in c]
#python bellow 3.6
#c1 = ['Unique_{}'.format(x) for x in c]
#c2 = ['Count_Unique_{}'.format(x) for x in c]

new_items_df[c1] = new_items_df[c].applymap(lambda x: set(x.lower().split(",")))
new_items_df[c2] = new_items_df[c1].applymap(len)

print (new_items_df)
              Name             Item   Unique_Name    Unique_Item  \
0  A,A,A,B,B,B,C,D   I1,I2,I3,I1,I2  {c, b, d, a}   {i1, i2, i3}   
1        X,Y,Z,Z,Z  I4,I1,I1,I88,I4     {y, x, z}  {i1, i4, i88}   

   Count_Unique_Name  Count_Unique_Item  
0                  4                  3  
1                  3                  3  

【讨论】:

  • 谢谢...我们也可以将您的代码的第 1 行和第 2 行结合起来,并在 1 行中完成吗?
  • @RahulAgarwal - 我认为不是,因为第二个 len 是从上面的行开始计算的 - 来自 new_items_df[c1]
【解决方案2】:

使用mergelambda 如下

df1 = df.merge(df.apply(lambda row: extractRow(row), axis=1), left_index=True, right_index=True)

完整的例子是

import pandas as pd

def extractRow(row):
    nameUnique = set(row['Name'].split(","))
    itemUnique = set(row['Item'].split(","))
    return pd.Series({
        'Unique_Name' : ','.join(nameUnique),
        'Unique_Item' : ','.join(itemUnique),
        'Count_Unique_name' : len(nameUnique),
        'Count_Unique_Item' : len(itemUnique)
    })

df = pd.DataFrame({
    'Name' : ('A,D,B,B,C,C', 'X,Y,Z,Z,Z'),
    'Item' : ('I1,I2,I3,I1,I2', 'I4,I1,I1,I88,I4')
})

df1 = df.merge(df.apply(lambda row: extractRow(row), axis=1), left_index=True, right_index=True)

print(df1)

【讨论】:

    猜你喜欢
    • 2017-09-09
    • 1970-01-01
    • 2021-11-11
    • 2021-12-21
    • 1970-01-01
    • 2020-02-20
    • 2017-10-04
    • 1970-01-01
    • 2017-04-17
    相关资源
    最近更新 更多