python - Python Pandas 中的嵌套循环 - 将子循环结果组合成连接的 df,并在文件名中使用组名保存
问题描述
我有一个看起来像下面的示例的 df。我正在尝试按组运行一个循环:
- 对组中的每个 id2 执行单独的 API 查询,将它们保存在内存中
- API 结果是 df(或者我强制转换为 df)[编辑]
- 将所有 id2 结果连接到一个新的数据帧中
- 将新的串联数据框保存为文件名中带有 id1 的新 .csv。
对于正确设置循环的示例,实际查询 API 的合适替代方法是将一些文本和 DESC 打印为新 .csv 中的新行。
我已经勾勒出我认为循环在 Python 和普通语言的混合中看起来像什么(在大写字母中带有 * *)。
我通常是 R 用户,但需要使用 Python 进行 API 查询。如何将下面的草图或大纲翻译成工作 Python?
import pandas as pd
data = [[1,1,'ab'],[1,2,'bc'],[1,3,'de'],[2,1,'gh'],[2,2,'hi'],[2,3,'jk'],[3,1,'kl'],[3,2,'lm']]
df = pd.DataFrame(data,columns=['id1','id2','DESCR'])
df_gp = df.groupby(id1)
- id1 是一个分组变量(大约 34K 个唯一值)
- id2标识组内的obs(每个id1有1-20个唯一的id2,它是id1内obs位置的数字指标,一个id变量)
- DESCR 是 id2 独有的,用于查询 API 以获取有关 id2 的信息
for name, group in df_gp:
for i in range(1, len(*WHAT_HERE_ID2?*)):
result[i] = *PRINT(DESCR) OR SOMETHING JUST TO CREATE A SAMPLE OBJECT_to be replaced w/API code*
result[i] = pd.DataFrame(result[i])
filename = 'myfileprefix_' + df_gp.loc[name] + '.csv'
all = *how to CONCATENATE result[i] through result[max(id2)] into one df*
all.to_csv(filename)
注意:我需要单独执行每个 id2 API 查询的全部原因是 b/c 如果我将所有 id2 作为一个组提交给 id1 的一个查询,它有时会超过查询限制(例如,如果多个 id2 返回大# 记录,它超过了查询限制,但是当我一次做一个 id2 时,这永远不会发生)。
结果应该是 3 个名为 .csv 的文件:
- myfileprefix_1.csv
- myfileprefix_2.csv
- myfileprefix_3.csv
里面包含所有 id2 查询的结果。
解决方案
iterrows
您可以在分组的 DataFrame 内迭代行:
# a function to be replaced with actual API call
def mock_api_call(v):
return f'api output for {v}'
# iterate over groups by `id1`
for id1, g in df_gp:
# iterate over rows inside each group
for i, r in g.iterrows():
g.loc[i, 'result'] = mock_api_call(r['DESCR'])
fn = f'myfileprefix{id1}.csv'
g.to_csv(fn)
myfileprefix1.csv
例如,中的输出将是:
id1 id2 DESCR result
0 1 1 ab api output for ab
1 1 2 bc api output for bc
2 1 3 de api output for de
PS 作为一个稍微不那么冗长的选项,您也可以使用apply
代替iterrows
:
for id1, g in df_gp:
g['result'] = g['DESCR'].apply(mock_api_call)
fn = f'myfileprefix{id1}.csv'
g.to_csv(fn)
更新:根据您对 API 调用返回 DataFrame 的说明:
for id1, g in df_gp:
# set up DataFrame to collect all API responses for the group
dfg = pd.DataFrame()
# iterate over rows inside each group
for i, r in g.iterrows():
# get DataFrame from API call
dfi = mock_api_call(r['DESCR'])
# if needed, add columns to API response DataFrame, e.g.
# dfi['DESCR'] = r['DESCR']
# ...
# concatenate new results to dfg
dfg = pd.concat([dfg, dfi], ignore_index=True)
fn = f'myfileprefix{id1}.csv'
dfg.to_csv(fn)
推荐阅读
- java - why maven fails to build for this project
- python-3.x - 如何从 YOUTUBE API 获得 Python 响应
- module - 创建一个模块,在 Drupal 8 中使用包含字段图像的表单实现新的 fieldType
- sql - 我正在尝试在 SQL 中构建一个视图,该视图识别和分组具有连续日期范围的记录,并返回最早和最晚日期
- jquery - 如何使用 jquery 查询 url 参数?
- javascript - 如何使用图像制作响应式 3 行
- amazon-web-services - 如何在 cloudwatch 日志中使用指标过滤器
- r - 在 R 中使用 textmineR 评估 LDA 预测 - 计算困惑度?
- python - 如何创建在不同句子中提取的标记列表的列表?
- angular - 无法将数据绑定到输入字段