代码之家  ›  专栏  ›  技术社区  ›  Sudhi

用字符串值在数据帧中追加列

  •  1
  • Sudhi  · 技术社区  · 7 年前

    我有一个例子,我试图将计算出的百分比值以一种可理解的格式附加到数据帧中名为df的列中。当我说“可理解的格式”时,列中的输出应该是 '40% Matched' ,就像下面的例子。

    df = pd.DataFrame({ 'Col1':[['Phone', 'Watch', 'Pen', 'Pencil', 'Knife'],['apple','orange','mango','cherry','banana','kiwi','tomato','avocado']], 'Col2': [['Phone', 'Watch', 'Pen', 'Pencil', 'fork'],['orange','avocado','kiwi','mango','grape','lemon','tomato']]})
    
    df['Matched Percent'] = 'No Match'
    
    for index,(lst1,lst2) in enumerate(zip(df['Col1'],df['Col2'])):
       if(lst1 == lst2):
          print('100% Matched')
       else:
          c1 = Counter(lst1)
          c2 = Counter(lst2)
          matching = {k: c1[k]+c2[k] for k in c1.keys() if k in c2}
          text = '% Matched'
          if len(lst1) > len(lst2):
             out = round(len(matching)/len(lst1)*100)
             #df['Matched Percent'].append(out,'% Matched')
             print(out,'% Matched')
          else:
             out = round(len(matching)/len(lst2)*100)
             #df['Matched Percent'].append(out,'% Matched')
             print(out,'% Matched')
    
    80 % Matched
    62 % Matched
    
    TypeError: cannot concatenate object of type "<class 'int'>"; only pd.Series, pd.DataFrame, and pd.Panel (deprecated) objs are valid
    

    df 它失败了。感谢您对如何解决这个问题的建议。

    2 回复  |  直到 7 年前
        1
  •  1
  •   jpp    7 年前

    你的逻辑似乎冗长。您可以使用列表:

    zipper = zip(map(set, df['Col1']), map(set, df['Col2']))
    df['Matched Percent'] = [len(c1 & c2) / max(len(c1), len(c2)) for c1, c2 in zipper]
    
    print(df)
    
                                                    Col1  \
    0                 [Phone, Watch, Pen, Pencil, Knife]   
    1  [apple, orange, mango, cherry, banana, kiwi, t...   
    
                                                    Col2  Matched Percent  
    0                  [Phone, Watch, Pen, Pencil, fork]            0.800  
    1  [orange, avocado, kiwi, mango, grape, lemon, t...            0.625  
    

    请注意,使用Pandas优化此类计算的空间不大,Pandas的设计并不是为了将列表串联起来。如果需要“pretty”输出,可以使用python3.6+支持的f字符串:

    print((df['Matched Percent']*100).map(lambda x: f'{x:.0f}% Matched'))
    
    0    80% Matched
    1    62% Matched
    Name: Matched Percent, dtype: object
    
        2
  •  0
  •   Yee Yang Tan    7 年前

    如果我没弄错你的问题,

    df = pd.DataFrame({ 'Col1':[['Phone', 'Watch', 'Pen', 'Pencil', 'Knife'],
                                ['apple','orange','mango','cherry','banana','kiwi','tomato','avocado']], 
                          'Col2': [['Phone', 'Watch', 'Pen', 'Pencil', 'fork'],
                                   ['orange','avocado','kiwi','mango','grape','lemon','tomato']]})
    
    df['Matched Percent'] = 'No Match'
    
    for index,(lst1,lst2) in enumerate(zip(df['Col1'],df['Col2'])):
        if(lst1 == lst2):
            print('100% Matched')
            df['Matched Percent'][index] = '{}% Matched'.format(100)
        else:
            c1 = Counter(lst1)
            c2 = Counter(lst2)
            matching = {k: c1[k]+c2[k] for k in c1.keys() if k in c2}
            text = '% Matched'
            if len(lst1) > len(lst2):
                out = round(len(matching)/len(lst1)*100)
                #df['Matched Percent'].append(out,'% Matched')
                print(out,'% Matched')
                df['Matched Percent'][index] = '{}% Matched'.format(out)
            else:
                out = round(len(matching)/len(lst2)*100)
                #df['Matched Percent'].append(out,'% Matched')
                print(out,'% Matched')
                df['Matched Percent'][index] = '{}% Matched'.format(out)
    

    我希望您的df符合以下条件:

    import pandas as pd
    
    result = 'blablabla'
    df = pd.DataFrame(data=[[1,2,3],[4,5,6]],
                      columns=['a','b','Match Percent'])
    s = pd.Series(index=df.columns)
    df = df.append(s, ignore_index=True)
    df['Match Percent'][df.shape[0]-1] = result
    
    print(df)
    
         a    b Match Percent
    0  1.0  2.0             3
    1  4.0  5.0             6
    2  NaN  NaN     blablabla
    

    更正:

    df = pd.DataFrame(data=[[1,2],[4,5]],
                  columns=['a','b'])
    
    df['Match Percent'] = (df['a']/df['b']*100).apply(lambda x: '{} Match'.format(x))
    
    
       a  b Match Percent
    0  1  2    50.0 Match
    1  4  5    80.0 Match