【问题标题】:Function that adds multiple columns to dataframe based on calculations - Pandas根据计算向数据框添加多列的函数 - Pandas
【发布时间】:2021-07-11 23:21:51
【问题描述】:

我有一个这样的数据框:

name:   ...  line: 
bobo    ...   10
amy     ...   5
amanda  ...   15

我想创建一个可用于多个数据帧的函数,它根据函数内的计算向数据帧添加新列。这是我正在尝试使用该功能执行的操作,但它不起作用。

def check(df, lines):
    
    for line in lines:
        df['big_line'] = (line*5, line)
        df['small_line'] = line*2
        df['massive_line'] = line*10
        df['line_word'] = line + ' line'
        
    return df

基本上,我想让它返回的是如下所示的数据框:

函数调用:

def check(df, df['line'])

返回:

name:   ...  line: big_line: small_line: massive_line: line_word:
bobo    ...   10   (50, 10)         20           100         10 line
amy     ...   5     (25, 5)         10            50          5 line
amanda  ...   15  ...............................................

如果有人能指出我正确的方向,那就太好了。谢谢。

我收到 big_line 错误,因为它是元组类型的对象。

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    使用计算每行输出的函数

    输入:

    df = pd.DataFrame({'line': [10,5,15]}, index=['bobo', 'amy', 'amanda']).rename_axis(index='name')
    

            line
    name        
    bobo      10
    amy        5
    amanda    15
    

    您可以定义一个返回系列的函数:

    def check(s):
        line = s['line']
        return pd.Series({'big_line': (line*5, line),
                          'small_line': line*2,
                          'massive_word': line*10,
                          'line_word': str(line)+' line'
                         })
    

    然后将其应用于行:

    df.apply(check, axis=1)
    

    输出:

            big_line  small_line  massive_word line_word
    name                                                
    bobo    (50, 10)          20           100   10 line
    amy      (25, 5)          10            50    5 line
    amanda  (75, 15)          30           150   15 line
    

    使用向量运算

    df['big_line']     = df['line'].apply(lambda x: (5*x, x))
    df['small_line']   = df['line']*2
    df['massive_line'] = df['line']*10
    df['line_word']    = df['line'].astype(str)+' line'
    

    【讨论】:

      【解决方案2】:

      您正在将序列分配给 Series 对象。您的序列只有 2 个元素,但数据框有超过 2 行。这个answer可以帮助你理解错误:

      def check(df, lines):
          for line in lines.to_list():
              df['big_line'] = f"({line*5}, {line})"
              df['small_line'] = line*2
              df['massive_line'] = line*10
              df['line_word'] = line + ' line'
          return df
      
      check(df, df['line'])
      

      输出:

          name    line    big_line    small_line  massive_line    line_word
      0   bobo      10    (75, 15)         30     150             15 line
      1   amy       5     (75, 15)         30     150             15 line
      2   amanda    15    (75, 15)         30     150             15 line
      

      编辑:根据您的评论,如果您想更新原始数据框的每一行,那么我建议修改您的原始函数以索引每个行号, 使用loc 方法:

      def check(df, lines):
        for index, line in enumerate(lines.to_list()):
            df.loc[index, 'big_line'] = f"({line*5}, {line})"
            df.loc[index, 'small_line'] = line*2
            df.loc[index, 'massive_line'] = line*10
            df.loc[index, 'line_word'] = line + ' line'
        return df
      

      输出:

          name    line    big_line    small_line  massive_line    line_word
      0   bobo    10     (50, 10)            20   100             10 line
      1   amy     5      (25, 5)             10   50               5 line
      2   amanda  15     (75, 15)            30   150             15 line
      

      【讨论】:

        【解决方案3】:

        如果你只想要一个字符串,你可以试试:

        df['big_line'] = f'({5*line}, {line})'
        

        如果它需要是一个元组,那么在创建字符串之后包含它:

        df['big_line'] = df.big_line.apply(lambda x: eval(x))
        

        【讨论】:

        • 我希望它为第一行等返回 (line*5, line) = (50, 10)。
        • 感谢您澄清@johnJones901(我应该更清楚地阅读问题)和编辑亨利埃克
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-02
        • 2015-05-25
        • 2020-03-12
        相关资源
        最近更新 更多