我的数据看起来像是字典列表:
wishlist_result [0] = {'userId':19814,'entityIds':[40、45、54、322]}
我将其转换为:
user_id:19814entity_id:40, user_id:19814entity_id:45, user_id:19814实体ID:54 user_id:19814实体ID:322
wishlist_data = pd.DataFrame()
for i in wishlist_result:
wishlist_from_dict = pd.DataFrame.from_dict(
wishlist_result[wishlist_result.index(i)])
wishlist_data = wishlist_data.append(
wishlist_from_dict, ignore_index=True)
wishlist_data = wishlist_data.rename(
index=str, columns={
"userId": "user_id",
"entityIds": "entity_id"
})
这段代码花费的时间太长,我有大约60k条记录,就像我上面提到的以任何方式在更短的时间内获得这种转换?
答案 0 :(得分:1)
将数据框用于“一切”通常不是最佳解决方案。代码可能变得不可读,并且构造许多小的数据帧也可能非常慢。我的解决方案使用普通的Python容器解决您的问题:
import pandas as pd
wishlist_result = [
{"userId": 19814, "entityIds": [40, 45, 54, 322]},
{"userId": 19814, "entityIds": [12, 22]},
]
def flatten(data):
flattened = []
for entry in data:
user_id = entry["userId"]
entity_ids = entry["entityIds"]
for entity_id in entity_ids:
row = dict(user_id=user_id, entity_id=entity_id)
flattened.append(row)
return flattened
rows = flatten(wishlist_result)
df = pd.DataFrame(rows, columns=["user_id", "entity_id"])
print(df)
输出
user_id entity_id
0 19814 40
1 19814 45
2 19814 54
3 19814 322
4 19814 12
5 19814 22
我以长度为60000的列表作为您的方法的基准,该列表复制了您的wishlist_result
示例。在旧Mac上,代码段的运行时间约为800毫秒。
如果您希望将其缩短,则嵌套列表理解也可以使用,运行时不会发生明显变化:
rows = [
{"user_id": entry["userId"], "entity_id": entity_id}
for entry in wishlist_result
for entity_id in entry["entityIds"]
]
我经常避免使用嵌套的for
循环进行列表解析,因为想要读取或重用我的代码的队友可能不知道执行顺序。但是这里涉及到的变量很清楚顺序。
答案 1 :(得分:0)
如果要串联很多帧,使用pd.concat
比每次添加都要快:
all_wishlists = []
for i in wishlist_result:
all_wishlists.append(
pd.DataFrame.from_dict(wishlist_result[wishlist_result.index(i)])
)
wishlist_data = pd.concat(all_wishlists, ignore_index=True)\
.rename(index=str,
columns={"userId": "user_id",
"entityIds": "entity_id"})
更好的是,我们可以将其更改为列表理解,并将整个过程简化为:
wishlist_data = pd.concat([pd.DataFrame.from_dict(wishlist_result[wishlist_result.index(i)])
for i in wishlist_result], ignore_index=True)\
.rename(index=str,
columns={"userId": "user_id",
"entityIds": "entity_id"})
您也不需要执行pd.DataFrame.from_dict(wishlist_result[wishlist_result.index(i)]) for i in wishlist_result
-您不需要找到该项目然后再次为其编制索引。相反,您可以执行以下操作:
wishlist_data = pd.concat([pd.DataFrame.from_dict(result)
for result in wishlist_result], ignore_index=True)\
.rename(index=str,
columns={"userId": "user_id",
"entityIds": "entity_id"})