如何在Pandas中为Twitter API返回的DataFrame批量填充tweet_id?
问题描述
我用以下代码将Twitter API V2的Retweeted_by接口返回的json_response转换为DataFrame:
df = pd.DataFrame(columns=["created_at", "username", "description", "tweet_id"]) #an empty dataframe to save data data_nested = pd.json_normalize(json_response['data']) df_temp = data_nested[["created_at", "username", "description"]].copy() df = pd.concat([df, df_temp], ignore_index=True) df.reset_index(inplace=True, drop=True)
示例json_response如下:
{ "data": [ { "created_at": "2020-01-01T12:24:45.000Z", "description": "This is a sample description", "id": "12345678", "name": "Sample Name", "username": "sample_name" } ], "meta": { "next_token": "sample_token", "result_count": 1 } }
我需要在循环中为每个响应对应的记录保存请求的tweet_id,明确每条数据所属的请求推文。但尝试df['tweet_id'] = tweet_id时,最后一个tweet_id会覆盖列中所有值;用索引定位赋值:
idx = df["username"].last_valid_index() if pd.isnull(idx) or idx is None: df.loc[0, "tweet_id"] = tweet_id else: df.loc[idx + 1, "tweet_id"] = tweet_id
当json_response的result_count>1时,只有一行会填充tweet_id,其余行都是NaN,求可行解决方案。
解决方案
核心思路是在临时DataFrame(df_temp)阶段就添加tweet_id列,让当前API响应返回的所有记录都带上对应的请求推文ID,之后再合并到主DataFrame中。
修改后的代码如下:
# 初始化主DataFrame df = pd.DataFrame(columns=["created_at", "username", "description", "tweet_id"]) # 循环中某次API请求对应的目标推文ID tweet_id = "目标推文的ID" # 处理API响应 data_nested = pd.json_normalize(json_response['data']) df_temp = data_nested[["created_at", "username", "description"]].copy() # 为临时DataFrame的所有行添加当前请求的tweet_id df_temp['tweet_id'] = tweet_id # 合并到主DataFrame df = pd.concat([df, df_temp], ignore_index=True)
原方法失效原因
df['tweet_id'] = tweet_id:这种赋值会覆盖整个列的所有行,循环中后续请求的推文ID会替换之前所有记录的值,最终所有记录都显示最后一次请求的ID。- 索引定位赋值:仅给单行赋值,当API返回多条记录时,只有新增的第一行会被填充,其余新增行的
tweet_id自然为NaN。
扩展:处理API分页场景
如果循环是处理API分页(用next_token获取下一页数据),只需保持tweet_id为当前请求的目标推文ID即可,逻辑不变:
df = pd.DataFrame(columns=["created_at", "username", "description", "tweet_id"]) target_tweet_id = "你要查询的推文ID" next_token = None while True: # 调用Twitter API,传入目标推文ID和分页token json_response = call_twitter_retweeted_by_api(target_tweet_id, next_token) data_nested = pd.json_normalize(json_response['data']) df_temp = data_nested[["created_at", "username", "description"]].copy() df_temp['tweet_id'] = target_tweet_id df = pd.concat([df, df_temp], ignore_index=True) # 检查是否有下一页 next_token = json_response['meta'].get('next_token') if not next_token: break
内容的提问来源于stack exchange,提问作者AneesBaqir
相关产品推荐
相关产品推荐

