使用列表推导式迭代Pandas数据帧

4

我可以用另一种方式解决这个问题,但我想确切了解为什么尝试使用列表推导式在 pandas DataFrame 上进行迭代不起作用。(这里的 a 是一个 Dataframe)

def func(a,seed1,seed2):
    for i in range(0,3):
        # Sum of squares. Results in a series containing 'date' and 'num' 
        sorted1 = ((a-seed1)**2).sum(1)
        sorted2 = ((a-seed2)**2).sum(1)

        # This makes a list out of the dataframe. 
        a = [a.ix[i] for i in a.index if sorted1[i]<sorted2[i]]
        b = [a.ix[i] for i in a.index if sorted1[i]>=sorted2[i]]
        # The above line throws the exception:
        # TypeError: 'builtin_function_or_method' object is not iterable

        # Throw it back into a dataframe...

        a = pd.DataFrame(a,columns=['A','B','C'])
        b = pd.DataFrame(b,columns=['A','B','C'])

        # Update the seed.
        seed1 = a.mean()
        seed2 = b.mean()

        print a.head()
        print "I'm computing."

你能添加完整的回溯信息以及seed1和seed2是什么吗? - Viktor Kerkez
@ViktorKerkez 使用带有三行的随机DataFrame,你会看到上面的错误(seed1/2在上面定义),但 OP 的 bug 更多是 Python 而不是 pandas。 :) - Andy Hayden
我关注了错误的事情 :) 我看到它们作为参数传递,但它们可以是任何东西... 标量、数据框架、猴子鸟... 无论如何,你的答案是正确的。 - Viktor Kerkez
@ViktorKerkez 哈!你说得很对,它们可能是这样的!我只是立即输入数字,看看会发生什么 :) - Andy Hayden
我经常在向pandas提交PR之前使用monkey-birds运行我的测试 :) - Phillip Cloud
1个回答

3
问题在于第一行之后,a不再是数据框架(DataFrame)。
a = [a.ix[i] for i in a.index if sorted1[i]<sorted2[i]]
b = [a.ix[i] for i in a.index if sorted1[i]>=sorted2[i]]

这是一个列表,因此没有索引属性(因此会出现错误)。

Python的一个技巧是在一行中同时定义它们,即:

a, b = [a.ix[i] for ...], [a.ix[i] for ...]

也许更好的选择是在这里使用不同的变量名(例如df)。
像你说的那样,在pandas中有更好的方法来做到这一点,显而易见的是使用掩码:
msk = sorted1 < sorted2

seed1 = df[msk].mean()
seed2 = df[~msk].mean()

是的,这是一个列表。但我的观点是,人们会认为:在这里,我们通过从数据框中访问值来构建列表...这应该没问题(?)...但事实并非如此。 - Michele Reilly
1
@MicheleReilly 但第一个列表推导式没问题。第二个会出错(因为a不再是原始的DataFrame)。 - Andy Hayden

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接