【问题标题】:pandas row specific apply熊猫行特定适用
【发布时间】:2012-06-25 14:32:18
【问题描述】:

类似于this R question,我想使用 Pandas 将函数应用于系列中的每个项目(或 DataFrame 中的每一行),但希望将此函数的索引或 id 用作该函数的参数排。作为一个简单的例子,假设一个人想要创建一个 [(index_i, value_i), ..., (index_n, value_n)] 形式的元组列表。使用简单的 Python for 循环,我可以做到:

In [1] L = []
In [2] s = Series(['six', 'seven', 'six', 'seven', 'six'],
           index=['a', 'b', 'c', 'd', 'e'])
In [3] for i, item in enumerate(s):
           L.append((i,item))
In [4] L
Out[4] [(0, 'six'), (1, 'seven'), (2, 'six'), (3, 'seven'), (4, 'six')]

但是必须有更有效的方法来做到这一点?也许像 Series.apply 这样更像熊猫的东西?实际上,我并不担心(在这种情况下)返回任何有意义的东西,但更多的是为了“应用”之类的效率。有什么想法吗?

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    如果您将 apply 方法与函数一起使用,则会发生 Series 中的每个项目都将映射到这样的函数。例如

    >>> s.apply(enumerate)
    a    <enumerate object at 0x13cf910>
    b    <enumerate object at 0x13cf870>
    c    <enumerate object at 0x13cf820>
    d    <enumerate object at 0x13cf7d0>
    e    <enumerate object at 0x13ecdc0>
    

    您要做的只是枚举系列本身。

    >>> list(enumerate(s))
    [(0, 'six'), (1, 'seven'), (2, 'six'), (3, 'seven'), (4, 'six')]
    

    例如,如果您想对所有实体的字符串求和怎么办?

    >>> ",".join(s)
    'six,seven,six,seven,six'
    

    apply 的一个更复杂的用法是:

    >>> from functools import partial
    >>> s.apply(partial(map, lambda x: x*2 ))
    a                ['ss', 'ii', 'xx']
    b    ['ss', 'ee', 'vv', 'ee', 'nn']
    c                ['ss', 'ii', 'xx']
    d    ['ss', 'ee', 'vv', 'ee', 'nn']
    e                ['ss', 'ii', 'xx']
    

    [编辑]

    遵循 OP 的澄清问题:不要将 Series (1D) 与 DataFrames (2D) http://pandas.pydata.org/pandas-docs/stable/dsintro.html#dataframe 混淆 - 因为我真的不明白如何谈论行。但是,您可以通过创建新系列在函数中包含索引(应用不会为您提供有关当前索引的任何信息):

    >>> Series([s[x]+" my index is:  "+x for x in s.keys()], index=s.keys())
    a      six index  a
    b    seven index  b
    c      six index  c
    d    seven index  d
    e      six index  e
    

    无论如何,我建议您切换到其他数据类型以避免大量内存泄漏。

    【讨论】:

    • 感谢@luke14free 关于枚举的指针。最后,我可能提供了一个过于简单的例子,但你确实提供了一个合适的答案。不过,我真正想要的是类似于您的第三个示例,并附加了一个条件,即指数是行或索引的函数...
    • 感谢@luke14free。最后,我按照你的建议做了,并通过重组我的数据以不同的方式解决了我的问题。
    【解决方案2】:

    这是一个巧妙的方法,使用 itertools 的 countzip

    import pandas as pd
    from itertools import count
    
    s = pd.Series(['six', 'seven', 'six', 'seven', 'six'],
                      index=['a', 'b', 'c', 'd', 'e'])
    
    In [4]: zip(count(), s)
    Out[4]: [(0, 'six'), (1, 'seven'), (2, 'six'), (3, 'seven'), (4, 'six')]
    

    不幸的是,效率只比enumerate(list(s))!

    【讨论】:

      猜你喜欢
      • 2018-08-08
      • 2021-09-26
      • 2018-05-20
      • 2017-06-24
      • 2017-09-21
      • 1970-01-01
      • 2020-11-23
      • 2016-09-16
      • 1970-01-01
      相关资源
      最近更新 更多