尝试删除空白行并将JSON行保留在数据框中

时间:2018-10-04 13:43:06

标签: python json python-3.x pandas

这非常非常奇怪,但是我想有一个简单的解决方案...我还没有找到。我正在尝试从数据框中删除所有空白行,并保留所有行中的数据。这是我的设置。

26                                                  []
27                                                  []
28                                                  []
29                                                  []
..                                                 ...
270  [{'id': 360014322992, 'default': True, 'name':...
271  [{'id': 360014322992, 'default': True, 'name':...
272  [{'id': 360014322992, 'default': True, 'name':...

最终,我想了解这个。

df1 = [{'id': 36001, 'default': False, 'name': 'Production', 'raw_name': 'Production', 'value': 'production'}, {'id': 3600, 'default': False, 'name': 'Development', 'raw_name': 'Development', 'value': 'development'}, {'id': 36001, 'default': False, 'name': 'Staging', 'raw_name': 'Staging', 'value': 'staging'}]
df2 = pd.DataFrame.from_dict(json_normalize(df1), orient='columns')
print(df2)

但是,这对于仅包含[]个字符的行不起作用。如何仅用[]删除行,或者如何编码以忽略[]字符并标准化此数据帧? TIA。

当我尝试此操作时:

df2 = df1[~df1.astype(bool)]
print(df2)

我明白了:

28                    []
29                    []
..                   ...
270                  NaN
271                  NaN

当我尝试这样做时:

df2 = df1[df1 != '[]']
print(df2)

我明白了:

28                                                  []
29                                                  []
..                                                 ...
270  [{'id': 360014322992, 'default': True, 'name':...
271  [{'id': 360014322992, 'default': True, 'name':...

当我尝试这样做时:

df2 = df1[df1.astype(bool)]
print(df2)

我明白了:

28                                                 NaN
29                                                 NaN
..                                                 ...
270  [{'id': 360014322992, 'default': True, 'name':...
271  [{'id': 360014322992, 'default': True, 'name':...

我仍然无法规范数据框中的JSON!

df2 = pd.DataFrame.from_dict(pd.io.json.json_normalize(df2), orient='columns')
print(df2)

AttributeError: 'str' object has no attribute 'values'

1 个答案:

答案 0 :(得分:1)

使用:

a = [{'id': 36001, 'default': False, 'name': 'Production', 'raw_name': 'Production', 'value': 'production'}, {'id': 3600, 'default': False, 'name': 'Development', 'raw_name': 'Development', 'value': 'development'}, 
     {'id': 36001, 'default': False, 'name': 'Staging', 'raw_name': 'Staging', 'value': 'staging'}]

s = pd.Series([[],[],a,a, np.nan])
print(s)
0                                                   []
1                                                   []
2    [{'id': 36001, 'default': False, 'name': 'Prod...
3    [{'id': 36001, 'default': False, 'name': 'Prod...
4                                                  NaN

#remove values with `NaN`s and empty lists
s1 = s[s.astype(bool) & s.notnull()]
print (s1)
2    [{'id': 36001, 'default': False, 'name': 'Prod...
3    [{'id': 36001, 'default': False, 'name': 'Prod...
dtype: object

#flatten values with DataFrame constructor 
df = pd.DataFrame([y for x in s1 for y in x])
print (df)
   default     id         name     raw_name        value
0    False  36001   Production   Production   production
1    False   3600  Development  Development  development
2    False  36001      Staging      Staging      staging
3    False  36001   Production   Production   production
4    False   3600  Development  Development  development
5    False  36001      Staging      Staging      staging

另一种仅通过dropna删除缺失值的解决方案:

df = pd.DataFrame([y for x in s.dropna() for y in x])
print (df)
   default     id         name     raw_name        value
0    False  36001   Production   Production   production
1    False   3600  Development  Development  development
2    False  36001      Staging      Staging      staging
3    False  36001   Production   Production   production
4    False   3600  Development  Development  development
5    False  36001      Staging      Staging      staging

另一个想法-仅过滤列表:

df = pd.DataFrame([y for x in s[[isinstance(x, list) for x in s]] for y in x])