如何从 for 循环构建和填充熊猫数据框? [复制]

Posted

技术标签:

【中文标题】如何从 for 循环构建和填充熊猫数据框? [复制]【英文标题】:How to build and fill pandas dataframe from for loop? [duplicate] 【发布时间】:2015-03-19 07:41:20 【问题描述】:

这是我正在运行的代码的一个简单示例,我希望将结果放入 pandas 数据框中(除非有更好的选择):

for p in game.players.passing():
    print p, p.team, p.passing_att, p.passer_rating()

R.Wilson SEA 29 55.7
J.Ryan SEA 1 158.3
A.Rodgers GB 34 55.8

使用此代码:

d = []
for p in game.players.passing():
    d = ['Player': p, 'Team': p.team, 'Passer Rating':
        p.passer_rating()]

pd.DataFrame(d)

我可以得到:

    Passer Rating   Player      Team
  0 55.8            A.Rodgers   GB

这是一个 1x3 数据框,我理解 为什么 它只有一行,但我不知道如何使其具有正确顺序的列的多行。理想情况下,该解决方案将能够处理 n 行数(基于 p),如果列数由请求的统计数据数设置,那将是很棒的(尽管不是必需的)。有什么建议?提前致谢!

【问题讨论】:

每次迭代都会覆盖列表,而不是追加 对,我明白它有什么问题,问题是我不知道如何让它正常工作。这只是我能得到的最接近的。 下面的答案会起作用。您也可以在循环中执行 d.append('Player': ...) 。列表上的 Python 文档非常好。 您还应该澄清您的问题以说明真正的问题:您在附加到空列表时遇到问题。 (您似乎非常了解如何从字典列表创建数据框) 虽然我想我明白你在说什么,但我相信我提出的问题实际上是我更喜欢,而我发布的代码是我之前能得到的最接近的寻求帮助。 【参考方案1】:

最简单的答案是 Paul H 所说的:

d = []
for p in game.players.passing():
    d.append(
        
            'Player': p,
            'Team': p.team,
            'Passer Rating':  p.passer_rating()
        
    )

pd.DataFrame(d)

但是,如果您真的想“从循环中构建和填充数据框”(顺便说一句,我不建议这样做),那么您可以这样做。

d = pd.DataFrame()

for p in game.players.passing():
    temp = pd.DataFrame(
        
            'Player': p,
            'Team': p.team,
            'Passer Rating': p.passer_rating()
        
    )

    d = pd.concat([d, temp])

【讨论】:

是否最好在列表中附加一个字典并仅在最后创建df,因为它具有卓越的性能,或者只是更好的可读性? 性能。引用docs: ...concat(因此append)会制作数据的完整副本,并且...不断重用此函数会产生显着的性能影响。 @NickMarinakis:我不明白你的评论:if you really want to "build and fill a dataframe from a loop", (which, btw, I wouldn't recommend)。那么如果不通过循环,你还能如何构建数据框呢? @***user2010:所以我的评论意味着你不应该创建一个数据框然后循环你的数据来填充它。每次您使用pd.concat 时,您都在制作数据的完整副本。这是非常低效的。相反,只需创建一个不同的数据结构(例如字典列表),然后将其一次性转换为数据帧。 @NickMarinakis:好的。在答案的第一部分中,您仍在使用循环(一次构建dictlist 一行),然后将整个内容一次转换为DataFrame。在第二种(更糟糕的)解决方案中,您一次通过 (concat) 附加一个 DataFrame 行。明白了。【参考方案2】:

使用列表推导试试这个:

import pandas as pd

df = pd.DataFrame(
    [p, p.team, p.passing_att, p.passer_rating()] for p in game.players.passing()
)

【讨论】:

开箱即用,这让我最接近我正在寻找的正确顺序的列,但我对 python 或 pandas 的了解还不够,无法说明它是否是 最佳答案。感谢大家的帮助。 这里的df 是什么? @Cai Pandas 数据框 @Amit 如df = pandas.DataFrame()?或者像from pandas import DataFrame as df @Amit 好的,那么在这种情况下,解决方案应该是d = df([p, p.team, p.passing_att, p.passer_rating()] for p in game.players.passing()) 吗? (也就是说,df 被调用而不是被索引?)【参考方案3】:

用你的数据创建一个元组列表,然后用它创建一个 DataFrame:

d = []
for p in game.players.passing():
    d.append((p, p.team, p.passer_rating()))

pd.DataFrame(d, columns=('Player', 'Team', 'Passer Rating'))

元组列表的开销应该比列表字典少。我在下面对此进行了测试,但请记住,在大多数情况下,将易于代码理解优先于性能。

测试功能:

def with_tuples(loop_size=1e5):
    res = []

    for x in range(int(loop_size)):
        res.append((x-1, x, x+1))

    return pd.DataFrame(res, columns=("a", "b", "c"))

def with_dict(loop_size=1e5):
    res = []

    for x in range(int(loop_size)):
        res.append("a":x-1, "b":x, "c":x+1)

    return pd.DataFrame(res)

结果:

%timeit -n 10 with_tuples()
# 10 loops, best of 3: 55.2 ms per loop

%timeit -n 10 with_dict()
# 10 loops, best of 3: 130 ms per loop

【讨论】:

我在我的代码中尝试了这个,它与元组一起工作得很好。只是想知道元组是不可变的。那么我们如何才能附加它们呢? @SumitPokhrel 元组是不可变的,但它们不会被append 改变。该列表被附加到,因此正在发生变异。 你不认为附加一些东西会改变或改变它的原始形式吗?如果 List 被 Append 改变,那么为什么 Tuple 没有被 Append 改变? @SumitPokhrel 因为您将元组附加到列表中:首先是res=[(1,2)],然后res.append((3,4)) 给出[(1,2),(3,4)] 所以元组没有突变【参考方案4】:

我可能是错的,但我认为@amit 接受的答案有一个错误。

from pandas import DataFrame as df
x = [1,2,3]
y = [7,8,9,10]

# this gives me a syntax error at 'for' (Python 3.7)
d1 = df[[a, "A", b, "B"] for a in x for b in y]

# this works
d2 = df([a, "A", b, "B"] for a in x for b in y)

# and if you want to add the column names on the fly
# note the additional parentheses
d3 = df(([a, "A", b, "B"] for a in x for b in y), columns = ("l","m","n","o"))

【讨论】:

以上是关于如何从 for 循环构建和填充熊猫数据框? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何在熊猫数据框中仅填充选定列的空值? [复制]

如何使用 for 循环过滤熊猫数据框中的观察结果?

如何在 for 循环中附加熊猫数据框中的行?

从多个字典填充熊猫数据框

Python:如何从熊猫数据框创建字典? [复制]

For循环子集化的熊猫数据框