我有一个包含 4m 行数据的数据集,我使用 pd.read_csv(chunk size...) 将其分成 block ,然后执行一些简单的数据清理代码以将其转换为我需要的格式。
tqdm.pandas()
print("Merging addresses...")
df_adds = chunk.progress_apply(merge_addresses, axis = 1)
[(chunk.append(df_adds[idx][0], ignore_index=True),chunk.append(df_adds[idx][1], \
ignore_index=True)) for idx in tqdm(range(len(chunk))) \
if pd.notnull(df_adds[idx][0]['street_address'])]
def merge_addresses(row):
row2 = pd.Series(
{'Org_ID' : row.Org_ID,
'org_name': row.org_name,
'street_address': row.street_address2})
row3 = pd.Series(
{'Org_ID' : row.Org_ID,
'org_name': row.org_name,
'street_address': row.street_address3})
return row2, row3
我使用 tqdm 来分析两个操作的速度,第一个,pandas apply 函数以大约 1.5k it/s 的速度运行良好,第二个,列表理解以大约 2k it/s 的速度开始,然后迅速下降至 200 次/秒。谁能帮我解释一下如何提高速度?
我的目标是获取 street_address 2 和 3 并将所有不为空的内容合并并复制到 street_address1 列中,并根据需要复制 org_id 和 org_name。
更新
我 try catch merge_addresses 中的任何 NaN 并将它们替换为字符串。我的目标是将地址 2 和地址 3 放入与地址 1 相同的列中的自己的行(带有 org_name 和 org_id(因此这两个字段将重复)。因此,同一 org_id 可能有三行,但地址不同。
df_adds = chunk.progress_apply(merge_addresses, axis = 1)
[(chunk.append(x[0]), chunk.append(x[1])) for x in tqdm(df_adds) if (pd.notnull(x[0][3]),pd.notnull(x[0][3]))]
def merge_addresses(row):
if pd.isnull(row.street_address2):
row.street_address2 = ''
if pd.isnull(row.street_address3):
row.street_address3 = ''
return ([row.Org_ID, row.pub_name_adj, row.org_name, row.street_address2], [row.Org_ID, row.pub_name_adj, row.org_name, row.street_address3])
我收到错误 '<' not supported between instances of 'str' and 'int', sort order is undefined for incomparable objects
result = result.union(other)
使用 tqdm,列表理解似乎可以工作,但速度非常慢(24 it/s)
更新
我的目标是实现以下目标:
我尝试过不同的 block 大小:
20k row = 70 it/s 100k row = 35 it/s 200k = 31 it/s
看起来更适合权衡的大小是 200k 行。
最佳答案
过于频繁地调用 DataFrame.append
可能会代价高昂 ( https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.append.html ):
Iteratively appending rows to a DataFrame can be more computationally intensive than a single concatenate. A better solution is to append those rows to a list and then concatenate the list with the original DataFrame all at once.
如果可以,请使用 pd.concat
来加快实现速度。
关于python - pandas 和列表理解的速度问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54121263/