我正在尝试通过迭代Pandas
(来自DataFrame
)中的数据来创建soup
BeautifulSoup4
。 This 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()
答案 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)