簡體   English   中英

將 DataFrame 轉換為帶有子字典的字典

[英]Convert DataFrame to dictionary with sub-dictionaries

這是我的數據幀

          name  filter      date     value
0     sum_buys     0.5  20200512  6.480628
1    sum_sells     0.5  20200512  5.019421
2     sum_buys     0.6  20200512  7.463128
3    sum_sells     0.6  20200512  5.836488
4     sum_buys     0.7  20200512  8.684414

我需要將其轉換為 2 個字典:

sum_buys[filter][date]
sum_sells[filter][date]

因此,例如:

sum_buys[0.5][20200512] = 6.480628
sum_buys[0.7][20200512] = 8.684414

如何在沒有迭代的情況下使用熊貓方法來做到這一點?

由於您只有少數幾列,因此您可以在數據幀上使用to_dict()方法,然后使用字典理解來獲得所需的數據結構。

創建嵌套字典不是您可以矢量化的東西,但是通過將迭代步驟移動到較小的字典而不是使用iterrows()如此答案中所示,您應該會看到一些性能提升。

import pandas as pd
from io import StringIO

data = StringIO("""
          name  filter      date     value
0     sum_buys     0.5  20200512  6.480628
1    sum_sells     0.5  20200512  5.019421
2     sum_buys     0.6  20200512  7.463128
3    sum_sells     0.6  20200512  5.836488
4     sum_buys     0.7  20200512  8.684414
""")

df = pd.read_csv(data, delim_whitespace=True)

sum_buys_data = (
    df[df["name"] == "sum_buys"]
    .set_index("filter")[["date", "value"]]
    .to_dict(orient="index")
)

sum_buys = {k : {v["date"] : v["value"]} for k, v in sum_buys_data.items()}

sum_buys

{0.5: {20200512: 6.480628},
 0.6: {20200512: 7.463128},
 0.7: {20200512: 8.684414}}

現在,但是如果您有很多列或想要更通用的方法怎么辦? 您仍然需要迭代,但我們可以調整defaultdict類,以便工廠知道丟失的鍵並以同樣的方式創建嵌套字典。 就時間而言,大約 20k 行在我的機器上大約 170ms 內轉換為嵌套字典,大約 780ms 內轉換為大約 200k 行。

# extra imports
import numpy as np
from collections import defaultdict
np.random.seed(0)

size = 100000 # let's create a slightly bigger data frame
df = pd.DataFrame(data={
    "name" : np.random.choice(["sum_buys", "sum_sells"], size=size),
    "filter" : np.random.choice(range(10), size=size),
    "date" : np.random.choice(range(1000), size=size),
    "value" : np.random.random(size)
}).drop_duplicates(subset=["name", "filter", "date"])

df.shape # (19861, 4)

# define a custom dictionary
class NestedDict(defaultdict):
    
    def __init__(self, f):
        super().__init__(None)
        self.f = f
        
    def __missing__(self, key):
        ret = NestedDict(self.f)
        self[key] = ret
        return ret

nested_dict = NestedDict(NestedDict)

for index, value in df.set_index(["name", "filter", "date"]).itertuples():
    n, f, d = index # unpack index into keys
    nested_dict[n][f][d] = value

nested_dict["sum_buys"][0][0] # 0.396...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM