【问题标题】:how do you pass multiple variables to pandas dataframe to use them with .map to create a new column如何将多个变量传递给 pandas 数据框以将它们与 .map 一起使用以创建新列
【发布时间】:2015-08-04 00:38:21
【问题描述】:

要将多个变量传递给普通的 python 函数,您可以编写如下内容:

def a_function(date,string,float):
      do something....
      convert string to int, 
      date = date + (float * int) days
      return date

当使用 Pandas DataFrames 时,我知道您可以根据其中的内容创建一个新列,如下所示:

df['new_col']) = df['column_A'].map(a_function)
# This might return the year from a date column
# return date.year

我想知道的是,您可以将多条数据传递给单个函数(如上面的第一个示例所示),您可以在创建新的 pandas DataFrame 列时使用多个列吗?

例如将日期 Y - M - D 的三个独立部分组合到一个字段中。

df['whole_date']) = df['Year','Month','Day'].map(a_function)

我在以下测试中遇到一个关键错误。

def combine(one,two,three):
    return one + two + three

df = pd.DataFrame({'a': [1,2,3], 'b': [2,3,4],'c': [4,5,6]})

df['d'] = df['a','b','b'].map(combine)

有没有一种方法可以使用.map 或其他将三列作为输入并返回一列的方法在 pandas DataFrame 中创建一个新列?

-> 示例输入:1, 2, 3

-> 示例输出:1*2*3

同样,还有一种方法可以让函数接受一个参数、一个日期并返回三个新的 pandas DataFrame 列;一个代表年、月和日?

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    有没有一种方法可以使用 .MAP 或其他将三列作为输入并返回一列的方法在 pandas 数据框中创建一个新列。例如输入为 1、2、3,输出为 1*2*3

    为此,您可以使用applyaxis=1。但是,不是使用三个单独的参数(每列一个)调用您指定的函数,而是使用每行的单个参数调用您的指定函数,并且该参数将是包含该行数据的系列。你可以在你的函数中考虑到这一点:

    def combine(row):
        return row['a'] + row['b'] + row['c']
    
    >>> df.apply(combine, axis=1)
    0     7
    1    10
    2    13
    

    或者您可以传递一个 lambda,将 Series 解包为单独的参数:

    def combine(one,two,three):
        return one + two + three
    
    >>> df.apply(lambda x: combine(*x), axis=1)
    0     7
    1    10
    2    13
    

    如果您只想传递特定的行,则需要通过使用列表在 DataFrame 上进行索引来选择它们:

    >>> df[['a', 'b', 'c']].apply(lambda x: combine(*x), axis=1)
    0     7
    1    10
    2    13
    

    注意双括号。 (这实际上与apply 没有任何关系;使用列表进行索引是从DataFrame 访问多个列的正常方式。)

    但是,重要的是要注意,在许多情况下您不需要使用apply,因为您可以只对列本身使用矢量化操作。上面的 combine 函数可以简单地使用 DataFrame 列本身作为参数来调用:

    >>> combine(df.a, df.b, df.c)
    0     7
    1    10
    2    13
    

    当“组合”操作可矢量化时,这通常效率更高。

    同样,还有一种方法可以让函数接受一个参数、一个日期并返回三个新的 pandas 数据框列;一个代表年、月和日?

    如上所述,有两种基本方法可以做到这一点:使用apply 的通用但非矢量化方式,以及更快的矢量化方式。假设你有一个这样的 DataFrame:

    >>> df = pandas.DataFrame({'date': pandas.date_range('2015/05/01', '2015/05/03')})
    >>> df
            date
    0 2015-05-01
    1 2015-05-02
    2 2015-05-03
    

    你可以定义一个函数,为每个值返回一个Series,然后apply它到列:

    def dateComponents(date):
        return pandas.Series([date.year, date.month, date.day], index=["Year", "Month", "Day"])
    
    >>> df.date.apply(dateComponents)
    11:    Year  Month  Day
    0  2015      5    1
    1  2015      5    2
    2  2015      5    3
    

    在这种情况下,这是唯一的选择,因为没有矢量化方式来访问各个日期组件。但是,在某些情况下,您可以使用矢量化操作:

    >>> df = pandas.DataFrame({'a': ["Hello", "There", "Pal"]})
    >>> df
            a
    0  Hello
    1  There
    2    Pal
    
    >>> pandas.DataFrame({'FirstChar': df.a.str[0], 'Length': df.a.str.len()})
       FirstChar  Length
    0         H       5
    1         T       5
    2         P       3
    

    这里再次通过直接对值进行操作而不是按元素应用函数来对操作进行矢量化。在这种情况下,我们有两个向量化操作(获取第一个字符和获取字符串长度),然后我们将结果包装在另一个 DataFrame 调用中,为这两种结果中的每一种创建单独的列。

    【讨论】:

    • 感谢 BrenBarn,您能否解释一下 .map 和 .apply 之间的区别以及什么是矢量化和元素计算。我不确定这些术语是什么意思?
    【解决方案2】:

    我通常使用apply 处理这种事情;它基本上是 Map 的 DataFrame 版本(轴参数让您决定是将函数应用于行还是列):

    df.apply(lambda row: row.a*row.b*row.c, axis =1)
    

    df.apply(np.prod, axis=1)
    
    0     8
    1    30
    2    72
    

    【讨论】:

      猜你喜欢
      • 2019-05-26
      • 1970-01-01
      • 1970-01-01
      • 2020-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多