繁体   English   中英

如何优化这段代码?

[英]How optimize this piece of code?

我的数据看起来像是字典列表:

wishlist_result [0] = {'userId':19814,'entityIds':[40、45、54、322]}

我将其转换为:

用户ID:19814实体ID:40,用户ID:19814实体ID:45,用户ID:19814实体ID:54,用户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条记录,就像我上面提到的那样,可以在更少的时间内获得这种转换?

将数据框用于“一切”通常不是最佳解决方案。 代码可能变得不可读,并且构造许多小的数据帧也可能非常慢。 我的解决方案使用普通的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循环来进行列表解析,因为想要读取或重用我的代码的队友可能不知道执行顺序。 但是这里涉及到的变量的顺序很清楚。

如果要串联很多帧,使用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_resultpd.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"})

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM