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