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

c.j*_*onn 50 python pandas

这是我正在运行的代码的一个简单示例,我希望将结果放入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
Run Code Online (Sandbox Code Playgroud)

使用此代码:

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

pd.DataFrame(d)
Run Code Online (Sandbox Code Playgroud)

我可以得到:

    Passer Rating   Player      Team
  0 55.8            A.Rodgers   GB
Run Code Online (Sandbox Code Playgroud)

这是一个1x3数据帧,我理解为什么它只有一行,但我无法弄清楚如何使列以正确的顺序排列多行.理想情况下,该解决方案能够处理n行(基于p),如果列数将根据请求的统计数设置,那将是很好的(尽管不是必需的).有什么建议?提前致谢!

Nic*_*kis 67

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

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

pd.DataFrame(d)
Run Code Online (Sandbox Code Playgroud)

但是如果你真的想"从一个循环中构建和填充一个数据框",(顺便说一句,我不建议),这就是你如何做到的.

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])
Run Code Online (Sandbox Code Playgroud)

  • 性能.引用[docs](http://pandas.pydata.org/pandas-docs/version/0.16.2/merging.html#concatenating-objects):...`concat`(因此`append`)使数据的完整副本,以及...不断重用此功能可以创建一个重要的性能影响. (3认同)
  • @ stackoverflowuser2010:所以我的评论意味着你不应该创建一个数据框,然后循环数据来填充它.每次使用`pd.concat`时,您都会制作完整的数据副本.这种效率非常低.相反,只需创建一个不同的数据结构(例如一个dicts列表),然后将其一次性转换为数据帧. (3认同)
  • 由于性能优越,还是只是更好的可读性,最好将一个字典附加到列表中并仅在最后创建“df”? (2认同)

Ami*_*mit 28

使用列表理解来尝试这个:

import pandas as pd

df = pd.DataFrame(
    [p, p.team, p.passing_att, p.passer_rating()] for p in game.players.passing()
)
Run Code Online (Sandbox Code Playgroud)

  • @Amit Ok,那么在那种情况下,解决方案应该是'd = df([p,p.team,p.passing_att,p.passer_rating()] for game in game.players.passing())`?(即所以`df`被调用而不是索引?) (4认同)
  • 这里的“ df”是什么? (2认同)
  • @Amit 与 `df = pandas.DataFrame()` 中的一样吗?或者像`from pandas import DataFrame as df`? (2认同)

Sea*_*123 22

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

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

pd.DataFrame(d, columns=('Player', 'Team', 'Passer Rating'))
Run Code Online (Sandbox Code Playgroud)

元组列表应该比列表字典具有更少的开销.我在下面对此进行了测试,但在大多数情况下,请记住优先考虑代码理解的简易性.

测试功能:

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)
Run Code Online (Sandbox Code Playgroud)

结果:

%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
Run Code Online (Sandbox Code Playgroud)