熊猫 |将带有类似列表/数组的字段的 json 文件读取到布尔列

Posted

技术标签:

【中文标题】熊猫 |将带有类似列表/数组的字段的 json 文件读取到布尔列【英文标题】:pandas | Read json file with list/array-like fields to Boolean columns 【发布时间】:2016-07-02 02:32:46 【问题描述】:

这是一个 JSON 字符串,其中包含一个对象列表,每个对象都嵌入了另一个列表。

[
  
    "name": "Alice",
    "hobbies": [
      "volleyball",
      "shopping",
      "movies"
    ]
  ,
  
    "name": "Bob",
    "hobbies": [
      "fishing",
      "movies"
    ]
  
]

使用pandas.read_json() 会变成这样的DataFrame:

  name      hobbies
  --------------------------------------
1 Alice     [volleyball, shopping, movies]
2 Bob       [fishing, movies]

但是,我想将列表展平为布尔列,如下所示:

  name      volleyball  shopping    movies  fishing 
  ----------------------------------------------------
1 Alice     True        True        True    False
2 Bob       False       False       True    True

即当列表包含一个值时,对应列中的字段用布尔值True 填充,否则用False 填充。

我也研究了pandas.io.json.json_normalize(),但这似乎也不支持这个想法。是否有任何内置方式(Python3 或 pandas)可以做到这一点?

(PS。我意识到您可以编写自己的代码来“规范化”字典对象,然后再将整个列表加载到 DataFrame 中,但我可能正在重新发明***,而且效率可能非常低方式)。

【问题讨论】:

【参考方案1】:

您可以执行以下操作:

In [56]: data = [
   ....:   
   ....:     "name": "Alice",
   ....:     "hobbies": [
   ....:       "volleyball",
   ....:       "shopping",
   ....:       "movies"
   ....:     ]
   ....:   ,
   ....:   
   ....:     "name": "Bob",
   ....:     "hobbies": [
   ....:       "fishing",
   ....:       "movies"
   ....:     ]
   ....:   
   ....: ]

 In [57]: df = pd.io.json.json_normalize(data, 'hobbies', ['name']).rename(columns=0:'hobby')

In [59]: df['count'] = 1

In [60]: df
Out[60]:
        hobby   name  count
0  volleyball  Alice      1
1    shopping  Alice      1
2      movies  Alice      1
3     fishing    Bob      1
4      movies    Bob      1

In [61]: df.pivot_table(index='name', columns='hobby', values='count').fillna(0)
Out[61]:
hobby  fishing  movies  shopping  volleyball
name
Alice      0.0     1.0       1.0         1.0
Bob        1.0     1.0       0.0         0.0

甚至更好:

In [88]: r = df.pivot_table(index='name', columns='hobby', values='count').fillna(0)

In [89]: r
Out[89]:
hobby  fishing  movies  shopping  volleyball
name
Alice      0.0     1.0       1.0         1.0
Bob        1.0     1.0       0.0         0.0

让我们动态生成“布尔”列的列表

In [90]: cols_boolean = [c for c in r.columns.tolist() if c != 'name']

In [91]: r = r[cols_boolean].astype(bool)

In [92]: print(r)
hobby fishing movies shopping volleyball
name
Alice   False   True     True       True
Bob      True   True    False      False

【讨论】:

谢谢,与此同时,我实际上已经通过迭代列表中的字典解决了这个问题。我会研究你的代码。【参考方案2】:

您可以将crosstabastype 转换为bool 一起使用:

df = pd.json_normalize(data, 'hobbies', ['name']).rename(columns=0:'hobby')
print df
        hobby   name
0  volleyball  Alice
1    shopping  Alice
2      movies  Alice
3     fishing    Bob
4      movies    Bob

print pd.crosstab(df.name, df.hobby).astype(bool)

hobby fishing movies shopping volleyball
name                                    
Alice   False   True     True       True
Bob      True   True    False      False

【讨论】:

df = pd.json_normalize (data, 'hobbies', ['name']).rename(columns=0:'hobby') as <string>:20: FutureWarning: pandas.io.json.json_normalize is deprecated, use pandas.json_normalize instead

以上是关于熊猫 |将带有类似列表/数组的字段的 json 文件读取到布尔列的主要内容,如果未能解决你的问题,请参考以下文章

熊猫数据框可以有列表的dtype吗?

熊猫:选择行 - 基于列表 - 带有重复行标签的 DF

将带有列表的字典转换为熊猫数据框

如何将带有列表值的熊猫列连接到一个列表中?

将熊猫数据框列表转换为 json

将列表中的字典追加到熊猫数据框