python - 将嵌套数据框转换为简单的数据框
问题描述
真的需要帮助,因为教程似乎没有解决这个问题。我花了一整天的时间,找不到解决方案。
我下载了 API 数据并从 json 转换为 python 字典格式。但是,字典很复杂,它有一个字典的字典。
这是字典的头部:
df[1]
Out[47]:
flight_date 2020-07-07
flight_status scheduled
departure {'airport': 'Findel', 'timezone': 'Europe/Luxe...
arrival {'airport': 'Francisco Sá Carneiro', 'timezone...
airline {'name': 'TAP Air Portugal', 'iata': 'TP', 'ic...
flight {'number': '6794', 'iata': 'TP6794', 'icao': '...
aircraft None
live None
Name: 1, dtype: object
在 Departure 和 Arrival 行中有不同机场的 iata çodes(例如:'iata':'LUX')。请参见下面的示例。
出发字典:
{'airport': 'Findel', 'timezone': 'Europe/Luxembourg', 'iata': 'LUX', 'icao': 'ELLX', 'terminal': None, 'gate': None, 'delay': None, 'scheduled': '2020-07-07T06:30:00+00:00', 'estimated': '2020-07-07T06:30:00+00:00', 'actual': None, 'estimated_runway': None, 'actual_runway': None}
我试图将这些复杂的字典简化为一个简单的表格,该表格由给定日期的出发 iata 代码和相应的到达 iata 代码列组成。
如果您对如何解决它有任何想法或知道好的文档,请发送。
非常感谢!
解决方案
对于字典中的单个值,您可以使用
df['departure_iata'] = df['departure'].apply(lambda item: item['iata'])
对于少数值,您可以使用类似的Series
df[['departure_airport', 'departure_iata']] = df['departure'].apply(lambda item: pd.Series([item['airport'], item['iata']]))
对于您可以使用的所有值,... = df['departure'].apply(pd.Series)
但它需要手动编写所有列的名称
df[['departure_airport', 'departure_timezone', 'departure_iata', 'departure_icao', 'departure_terminal', 'departure_gate', 'departure_delay', 'departure_scheduled', 'departure_estimated', 'departure_actual', 'departure_estimated_runway', 'departure_actual_runway'] ] = df['departure'].apply(pd.Series)
使用assign
你可以使它更简单,但它不会departure_
为新列添加前缀 - 如果你想对arrival
具有相同名称的人做同样的事情,它可能会出现问题。
df = df.assign(**df['departure'].apply(pd.Series))
但你可以在Series
df = df.assign(
**df['departure'].apply(
lambda item: pd.Series({'departure_'+key:val for key,val in item.items()})
)
)
编辑:简单一点add_prefix()
df = df.assign(**df['departure'].apply(lambda item:pd.Series(item).add_prefix('departure_')))
或者
df = df.assign(**df['departure'].apply(pd.Series).add_prefix('departure_'))
最少的工作代码
import pandas as pd
data = {
'A': [1,2,3],
'B': [4,5,6],
'departure': [
{'airport': 'Findel', 'timezone': 'Europe/Luxembourg', 'iata': 'LUX', 'icao': 'ELLX', 'terminal': None, 'gate': None, 'delay': None, 'scheduled': '2020-07-07T06:30:00+00:00', 'estimated': '2020-07-07T06:30:00+00:00', 'actual': None, 'estimated_runway': None, 'actual_runway': None},
{'airport': 'Findel', 'timezone': 'Europe/Luxembourg', 'iata': 'LUX', 'icao': 'ELLX', 'terminal': None, 'gate': None, 'delay': None, 'scheduled': '2020-07-07T06:30:00+00:00', 'estimated': '2020-07-07T06:30:00+00:00', 'actual': None, 'estimated_runway': None, 'actual_runway': None},
{'airport': 'Findel', 'timezone': 'Europe/Luxembourg', 'iata': 'LUX', 'icao': 'ELLX', 'terminal': None, 'gate': None, 'delay': None, 'scheduled': '2020-07-07T06:30:00+00:00', 'estimated': '2020-07-07T06:30:00+00:00', 'actual': None, 'estimated_runway': None, 'actual_runway': None},
]
} # columns
df = pd.DataFrame(data)
print(df)
df['departure_iata'] = df['departure'].apply(lambda item: item['iata'])
#df['departure_iata'] = df['departure'].str['iata']
print(df['departure_iata'])
df[['departure_airport', 'departure_iata']] = df['departure'].apply(lambda item: pd.Series([item['airport'], item['iata']]))
print(df[['departure_airport', 'departure_iata']])
df[['departure_airport', 'departure_timezone', 'departure_iata', 'departure_icao', 'departure_terminal', 'departure_gate', 'departure_delay', 'departure_scheduled', 'departure_estimated', 'departure_actual', 'departure_estimated_runway', 'departure_actual_runway'] ] = df['departure'].apply(pd.Series)
print(df[['departure_airport', 'departure_iata', 'departure_timezone']])
#----
df = df.assign(**df['departure'].apply(pd.Series))
print(df)
df = df.assign(
**df['departure'].apply(
lambda item: pd.Series({'departure_'+key:val for key,val in item.items()})
)
)
print(df)
df = df.assign(**df['departure'].apply(lambda item:pd.Series(item).add_prefix('departure_')))
print(df)
df = df.assign(**df['departure'].apply(pd.Series).add_prefix('departure_'))
print(df)
顺便说一句:你assign()
也可以使用concat()
df = pd.concat([df, df['departure'].apply(pd.Series).add_prefix('departure_')], axis=1)
print(df.columns)
你甚至可以删除列'departure'
df = pd.concat([df.drop(['departure'], axis=1), df['departure'].apply(pd.Series).add_prefix('departure_')], axis=1)
print(df.columns)
编辑:
将行转换为列
df = df.T
在示例中,我必须使用apply(eval)
因为我将字典作为字符串并且必须转换为 Python 字典。
text = '''flight_date 2020-07-07
flight_status scheduled
departure {'airport': 'Findel', 'timezone': 'Europe/Luxe...'}
arrival {'airport': 'Francisco Sá Carneiro', 'timezone':'...'}
airline {'name': 'TAP Air Portugal', 'iata': 'TP', 'icao':'...'}
flight {'number': '6794', 'iata': 'TP6794', 'icao': '...'}
aircraft None
live None'''
import pandas as pd
import io
df = pd.read_csv(io.StringIO(text), sep='\s{2,}', header=None)
df.rename(columns={0:'index'}, inplace=True)
df.index = df['index']
df = df.drop('index', axis=1)
print(df)
print('---')
df = df.T
print(df)
print('---')
df['departure'] = df['departure'].apply(eval)
df['departure_airport'] = df['departure'].apply(lambda item: item['airport'])
print(df['departure_airport'])
推荐阅读
- react-native - 滚动到 react-native scrollview 动态子项
- hyperledger-fabric - 错误:连接 ECONNREFUSED 127.0.0.1:7054]
- json - 如何在 presto 中提取嵌套的 JSON 对象?
- mysql - 如何使用 row_number、lag/lead、join SQL 解决问题
- sql - 需要使用 SQL 将两行数据合并为一行
- ios - Swift:检测屏幕上的任何变化
- c++ - 有没有办法通过作为用户输入的字符串来创建类实例名称?
- javascript - 无法读取未定义的属性“点击”
- c# - LINQ to Mocks:访问方法参数
- c# - 如何生成连续几天的运行数字?