Pandas:使用 for 循环添加新列和值

Pandas: Adding a new column and values with a for loop

我有一个数据框:df1,B 列值在列表中列出

df1 = pd.DataFrame({'A': ['aa', 'bb'], 
                'B': [[[1,'cc'],[2,'aa']],[[3,'dd'],[4,'bb']]], 
                'ADDED': [10, 20]})

和数据帧:df2

df2 =  pd.DataFrame({'id': [1, 2, 3, 4], 
                     'number': [55, 66, 77, 88]})                             
                      
    

我正在尝试对 A 列和 B 列进行字符串匹配

df3 = pd.DataFrame()
for i,val in enumerate(df1['A'].values):
   for val2 in df1['B'][i]:
       score = fuzz.partial_ratio(val, val2)
       if score > 99:
           df3 = df3.append(df2.loc[df2['id'] == val2[0], 'number'])

我的结果是这样的:

df3 = pd.DataFrame({'1': [66, 'NaN'], '3': ['NaN', 66]}, index=['number', 'number'])
  

有没有一种有效的方法,结果是这样的:(从 df1 添加了额外的列)

df4 = pd.DataFrame({'number': [66, 88], 'ADDED': [10, 20]})

使用 explode 可以让您查看每个子列表而无需对其进行迭代。然后你可以使用模糊匹配来过滤 df1 并使用默认加入索引的 join 来获得你的结果。

from fuzzywuzzy import fuzz
df1 = pd.DataFrame({'A': ['aa', 'bb'], 
                'B': [[[1,'cc'],[2,'aa']],[[3,'dd'],[4,'bb']]], 
                'ADDED': [10, 20]})

df2 =  pd.DataFrame({'id': [1, 2, 3,4], 'number': [55, 66, 77, 88]})

df1 = df1.explode('B')
# Rowwise fuzzy match
df1 = df1[df1.apply(lambda x: fuzz.partial_ratio(x['A'], x['B'][1]) > 99, axis=1)]

df2[['number']].join(df1[['ADDED']], how='inner')

输出

    number  ADDED
0       55     10
1       66     20

我认为这段代码适合我:

df1 = pd.DataFrame({'A': ['aa', 'bb'], 
            'B': [[[1,'cc'],[2,'aa']],[[3,'dd'],[4,'bb']]], 
            'ADDED': [10, 20]})
df2 =  pd.DataFrame({'id': [1, 2, 3, 4], 'number': [55, 66, 77, 88]})
df1 = df1.explode('B')
df1 = df1[df1.apply(lambda x: fuzz.partial_ratio(x['A'], x['B'][1]) > 99, 
       axis=1)]
df1['number'] = df1['B'].apply(lambda x: df2.loc[df2['id']==x[0], 
                'number'].values[0])

输出:

df1
    A        B  ADDED  number
0  aa  [2, aa]     10      66
1  bb  [4, bb]     20      88

谢谢你,克里斯。