使用.loc创建DataFrame以使用放大进行设置

时间:2014-09-15 00:43:37

标签: python python-2.7 pandas

我正在尝试通过迭代Pandas(来自DataFrame)中的数据来创建soup BeautifulSoup4This SO post建议使用.loc方法Set With Englargement创建DataFrame

然而,这种方法需要很长时间才能运行(对于30,000行和5列的df,大约需要8分钟)。有没有更快的方法来做到这一点。这是我的代码:

import requests
from bs4 import BeautifulSoup
import pandas as pd

url = "http://api.turfgame.com/v3/zones"
r = requests.get(url)
soup = BeautifulSoup(r.content)

col_names = ["name", "lat", "lng", "points_take", "points_hold"]
dfi = pd.DataFrame(columns=col_names)

def get_all_zones():

    for attr in soup.find_all("zone"):
        col_values= [attr.get("name"), attr.get("lat"), attr.get("lng"), attr.get("points_take"), attr.get("points_hold")]
        pos = len(dfi.index)
        dfi.loc[pos] = col_values

    return dfi

get_all_zones()

1 个答案:

答案 0 :(得分:4)

避免

df.loc[pos] = row

尽可能。 Pandas NDFrames将基础数据存储在(通用dtype)块中(对于DataFrames)与列关联。 DataFrame是基于列的数据结构,而不是基于行的数据结构。

要访问行,DataFrame必须访问每个块,选择适当的行并将数据复制到新的系列中。

向现有DataFrame添加行也很慢,因为必须将新行附加到每个块,并将新数据复制到新行中。更糟糕的是,数据块必须在内存中连续。因此,添加新行可能会强制Pandas(或NumPy)为块分配一个全新的数组,而 all 该块的数据必须被复制到一个更大的数组中,以容纳该行。所有复制都会让事情变得非常缓慢。所以尽可能避免使用它。

这种情况下的解决方案是将数据附加到Python列表并在最后一次创建DataFrame:


import requests
from bs4 import BeautifulSoup
import pandas as pd

url = "http://api.turfgame.com/v3/zones"
r = requests.get(url)
soup = BeautifulSoup(r.content)

col_names = ["name", "lat", "lng", "points_take", "points_hold"]
data = []    

def get_all_zones():    
    for attr in soup.find_all("zone"):
        col_values = [attr.get("name"), attr.get("lat"), attr.get(
            "lng"), attr.get("points_take"), attr.get("points_hold")]
        data.append(col_values)
    dfi = pd.DataFrame(data, columns=col_names)

    return dfi

dfi = get_all_zones()
print(dfi)