Python 如何从for循环构建和填充数据帧?

Python 如何从for循环构建和填充数据帧?,python,pandas,Python,Pandas,下面是我正在运行的代码的一个简单示例,我希望将结果放入pandas数据帧中(除非有更好的选项): 使用此代码: 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

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

使用此代码:

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),如果列的数量由请求的统计数据的数量设置,那将是非常好的(尽管不是必需的)。有什么建议吗?提前谢谢

尝试使用列表理解:

import pandas as pd

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

最简单的答案是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])

使用数据创建元组列表,然后使用它创建数据帧:

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

我可能错了,但我认为@amit接受的答案有一个bug

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"))


你每次迭代都会覆盖你的列表,而不是添加正确的,我知道它有什么问题,问题是我不知道如何使它正确工作。这是我能得到的最接近的答案。下面的答案会有用的。您也可以在循环中执行
d.append({'Player':…})
。列表上的Python文档非常好。您还应该澄清您的问题以说明真正的问题:您在添加到空列表时遇到了问题。(你似乎非常了解如何从字典列表中创建数据帧)虽然我想我理解你的意思,但我相信我问的问题实际上是我更喜欢的,虽然我发布的代码是在请求帮助之前我能得到的最接近的代码。开箱即用,这使我最接近我所寻找的内容,列的顺序正确,但我对python或pandas都不太了解,所以不能说这是不是最好的答案。谢谢大家的帮助。这里是什么dataframe@Amit如
df=pandas.DataFrame()
?或者像从pandas导入数据框为df一样,?@Amit Ok,那么在这种情况下,解决方案应该是
d=df([p,p.team,p.passing_att,p.passer_rating()]对于游戏中的p.players.passing())
?(即调用
df
而不是编制索引?)最好将dict附加到列表中,并仅在末尾创建
df
,这是因为性能优越,还是因为可读性更好?性能更好。引用:…
concat
(因此,
append
)生成数据的完整副本,并且。。。不断重复使用此函数可能会对性能造成重大影响。@Nickmariankis:我不理解你的评论:
如果你真的想“从循环中构建并填充数据帧”(顺便说一句,我不建议这样做)
。那么,如果不是通过循环,您还可以如何构建数据帧呢?@stackoverflowuser2010:所以我的评论意味着您不应该创建一个数据帧,然后在数据上循环以填充它。每次使用
pd.concat
都是在制作数据的完整副本。效率太低了。相反,只需创建一个不同的数据结构(例如一个dict列表),然后立即将其转换为一个数据帧。@Nickmariankis:好的。在回答的第一部分中,您仍然在使用循环(一次创建一行
dict
列表),然后立即将整个内容转换为数据帧。在第二种(更糟糕的)解决方案中,您一次通过(
concat
)追加一行数据帧。明白了。我在我的代码中尝试了这个,它在元组中工作得非常好。只是想知道元组是不可变的。那么我们如何才能附加它们呢?@SumitPokhrel元组是不可变的,但它们不会被
附加
变异。列表被附加到列表中,因此是被改变的。你不认为附加某些东西是在改变或改变它的原始形式吗?若列表是由Append变异的,那个么为什么元组不是由Append变异的呢?
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"))