【问题标题】:Reading unstructured dictionaries in pandas dataframe在熊猫数据框中读取非结构化字典
【发布时间】:2020-01-29 19:24:24
【问题描述】:

我正在尝试从我从 json 文件中读取的字典集合中创建一个 pandas 数据框。字典如下 -

d1 = {"DisplayName": "Test_drive", "permissions": {"read": True, "read_acp": True, "write": True, "write_acp": True}}
d2= {"DisplayName": "Log delivery","URI": "http://test_drive.com/Logs", "permissions": {"read": False, "read_acp": True, "write": True, "write_acp": False}}

我正在尝试将这些放入熊猫数据框中。当我尝试在如下数据框中读取它们时 -

df = pd.DataFrame(d) **or** df = pd.DataFrame.from_dict(d)

它会生成这个 -

                DisplayName  permissions
read       Test_drive         True
read_acp   Test_drive         True
write      Test_drive         True
write_acp  Test_drive         True

或如下阅读 -

df1 = pd.DataFrame(d).Transpose()

它会生成这个 -

                         read          read_acp             write         write_acp
DisplayName  Test_drive  Test_drive  Test_drive  Test_drive
permissions              True              True              True              True

我正在尝试阅读这些字典并将它们加入一个数据框 -

**DisplayName**              **read**          **read_acp**             **write**         **write_acp**         URI
Test_drive         True              True              True              True         NA
Log delivery            False             True              True             False         http://test_drive.com/Logs

有什么pytonic方法可以做到这一点吗?

【问题讨论】:

  • AWSAUDPL203027QA 在您想要的输出中,但不在您的输入 d1 或 d2 中。那是从哪里来的?您确定您想要的输出与您列出的输入 d1/d2 匹配吗?
  • @MaxPower - 修复了数据框以反映它。

标签: python pandas dataframe dictionary


【解决方案1】:

通过追加创建数据框,然后使用枢轴重塑为您需要的结构

df = pd.DataFrame.from_dict(d1).append(pd.DataFrame.from_dict(d2))
df.reset_index().pivot(index='DisplayName', columns='index', values='permissions')

要包含 URI

>>> df.reset_index().pivot(index='DisplayName', columns='index', values=['permissions', 'URI'])
             permissions                                                  URI                                                                                    
index               read read_acp write write_acp                        read                    read_acp                       write                   write_acp
DisplayName                                                                                                                                                      
Log delivery       False     True  True     False  http://test_drive.com/Logs  http://test_drive.com/Logs  http://test_drive.com/Logs  http://test_drive.com/Logs
Test_drive          True     True  True      True                         NaN                         NaN                         NaN                         NaN

【讨论】:

  • @Vishnudev- 这会在执行此操作时删除名为 URL 的列之一。
  • @Steve_Greenwood:这是一个很好的答案(现在更新以解决您的评论)。在枢轴的values 参数中包含要转置的两列比我对转置和合并的回答要好得多。我建议你接受这个答案(点击它左边的绿色勾号)
  • 答案很好,但它创建了更多需要删除的列“URI”。 df = pd.concat([pd.Series(d1),pd.Series(d2)],axis=1).transpose() df = pd.concat([df.drop(['permissions'],axis=1 ),df['permissions'].apply(pd.Series)],axis=1)
  • @Steve_Greenwood 您的问题所需输出中有“URI”列
  • @MaxPower :是的,但枢轴实际上是为 URI 创建 4 列。 “test_drive.com/Logs”在子标题下重复了 4 次 - 在上面的答案中以及当我尝试这样做时,read、read_acp、write 和 write_acp。
【解决方案2】:
import pandas as pd

# Input Data
d1 = {"DisplayName": "Test_drive", "permissions": {"read": True, "read_acp": True, "write": True, "write_acp": True}}
d2= {"DisplayName": "Log delivery","URI": "http://test_drive.com/Logs", "permissions": {"read": False, "read_acp": True, "write": True, "write_acp": False}}

# Convert to DataFrame
dicts = [d1, d2]
df_rows = [pd.DataFrame(d) for d in dicts]
df = pd.concat(df_rows, axis=0).reset_index(drop=False)

# Reshape As Desired
tp1 = df.pivot(index='DisplayName', columns='index', values='permissions')
answer = tp1.merge(df[['DisplayName', 'URI']].drop_duplicates(), 
                   how='left', 
                   left_index=True, 
                   right_on='DisplayName').set_index('DisplayName')

输出:

>>> answer
               read  read_acp  write  write_acp                         URI
DisplayName                                                                
Log delivery  False      True   True      False  http://test_drive.com/Logs
Test_drive     True      True   True       True                         NaN

【讨论】:

    【解决方案3】:

    感谢 VishnudevMax Power 的帮助。我认为以下答案为我提供了我试图获得的确切数据框。

    d1 = {"DisplayName": "Test_drive", "permissions": {"read": True, "read_acp": True, "write": True, "write_acp": True}}
    d2= {"DisplayName": "Log delivery","URI": "http://test_drive.com/Logs", "permissions": {"read": False, "read_acp": True, "write": True, "write_acp": False}}
    df = pd.concat([pd.Series(d1),pd.Series(d2)], axis=1).transpose()
    df = pd.concat([df.drop(['permissions'], axis=1),df['permissions'].apply(pd.Series)],axis=1)
    
    **DisplayName                         URI   read  read_acp  write  write_acp**
    0    Test_drive                         NaN   True      True   True       True
    1  Log delivery  http://test_drive.com/Logs  False      True   True      False
    

    【讨论】:

      猜你喜欢
      • 2016-03-10
      • 2016-10-17
      • 2017-08-02
      • 2017-02-27
      • 1970-01-01
      • 2021-07-17
      • 1970-01-01
      • 2021-02-15
      • 2015-06-02
      相关资源
      最近更新 更多