如何根据数据框中列的值在 pandas 中创建新列(pivot 或 unpivot?)
how to create new columns in pandas based on a column's values within a dataframe (pivot or unpivot ? )
我有来自 NOAA 气象站的以下天气数据。
stn wban date temp count_temp dewp count_dewp slp count_slp stp count_stp visib
486990 99999 1/1/2020 82.6 24 73.9 24 9999.9 0 999.9 0 6.2
486980 99999 1/1/2020 82.4 24 74.4 24 9999.9 0 999.9 0 6.3
486990 99999 2/1/2020 82 24 74.7 24 9999.9 0 999.9 0 6.1
486980 99999 2/1/2020 82.2 24 75.1 24 9999.9 0 999.9 0 6.1
486990 99999 3/1/2020 82.1 24 75.2 24 9999.9 0 999.9 0 6.2
... ... ... ... ... ... ... ... ... ... ... ...
486990 99999 29/12/2020 79.3 24 73.5 24 9999.9 0 999.9 0 5.9
486980 99999 30/12/2020 81.8 24 74.6 24 9999.9 0 999.9 0 6.1
486990 99999 30/12/2020 81.8 24 72.7 24 9999.9 0 999.9 0 6.2
486980 99999 31/12/2020 81.1 24 75 24 9999.9 0 999.9 0 6.2
486990 99999 31/12/2020 80.4 24 72.9 24 9999.9 0 999.9 0 6.1
我希望数据框由 'wban'
列分隔
我希望它看起来像那样,
date_486990 temp_486990 count_temp_486990 dewp_486990 count_dewp_486990 slp_486990 count_slp_486990 stp_486990 count_stp_486990 visib_486990 date_486980 temp_486980 count_temp_486980 dewp_486980 count_dewp_486980 slp_486980 count_slp_486980 stp_486980 count_stp_486980 visib_486980
1/1/2020 82.6 24 73.9 24 9999.9 0 999.9 0 6.2 1/1/2020 82.4 24 74.4 24 9999.9 0 999.9 0 6.3
2/1/2020 82 24 74.7 24 9999.9 0 999.9 0 6.1 2/1/2020 82.2 24 75.1 24 9999.9 0 999.9 0 6.1
..............................
30/12/2020 81.8 24 72.7 24 9999.9 0 999.9 0 6.2 30/12/2020 81.8 24 74.6 24 9999.9 0 999.9 0 6.1
31/12/2020 80.4 24 72.9 24 9999.9 0 999.9 0 6.1 31/12/2020 81.1 24 75 24 9999.9 0 999.9 0 6.2
这里有一张图片方便参考
我知道这有点难看,但基本上我希望 wban 列中的每个唯一值在右侧都有自己的一组列,但与其余数据共享相同的日期。
我该怎么做,我是否必须逆轴旋转或融化或交叉表或其他东西?我不确定使用什么功能或从哪里开始解决这个问题。
有什么想法吗?
我知道路途遥远,
首先我通过 stn
.
过滤数据帧
然后我运行一个for循环并在日期合并每一帧。
frame = df[df.stn.unique()]
for i in df.stn.unique():
temp = df[df.stn==i]
frame.merge(temp, how='left', on='date')
是否有更短更高效的 pandas 函数来执行此操作?
有些地方不明确,您描述了 wban
用作主元的值,但在提供的数据集中,具有“486990”和“486980”的列是 stn
。对于其余部分,我会认为您想按 stn
进行调整。如果不是这种情况,请更正您的问题。
您可以使用 pandas.DataFrame.pivot
, specify all columns but stn
and wban
as values. Then rework the MultiIndex
as a single index by concatenating the names. Finally, use dropna
删除数据不完整的行(可选)
df2 = df.pivot(index='date',
columns=['stn'],
values=df.columns.drop(['stn', 'wban'])
)
df2.columns = ['%s_%s' % cols for cols in df2.columns]
df2.dropna()
输出:
date_486980 date_486990 temp_486980 temp_486990 count_temp_486980 count_temp_486990 dewp_486980 dewp_486990 count_dewp_486980 count_dewp_486990 slp_486980 slp_486990 count_slp_486980 count_slp_486990 stp_486980 stp_486990 count_stp_486980 count_stp_486990 visib_486980 visib_486990
date
1/1/2020 1/1/2020 1/1/2020 82.4 82.6 24 24 74.4 73.9 24 24 9999.9 9999.9 0 0 999.9 999.9 0 0 6.3 6.2
2/1/2020 2/1/2020 2/1/2020 82.2 82 24 24 75.1 74.7 24 24 9999.9 9999.9 0 0 999.9 999.9 0 0 6.1 6.1
30/12/2020 30/12/2020 30/12/2020 81.8 81.8 24 24 74.6 72.7 24 24 9999.9 9999.9 0 0 999.9 999.9 0 0 6.1 6.2
31/12/2020 31/12/2020 31/12/2020 81.1 80.4 24 24 75 72.9 24 24 9999.9 9999.9 0 0 999.9 999.9 0 0 6.2 6.1
我有来自 NOAA 气象站的以下天气数据。
stn wban date temp count_temp dewp count_dewp slp count_slp stp count_stp visib
486990 99999 1/1/2020 82.6 24 73.9 24 9999.9 0 999.9 0 6.2
486980 99999 1/1/2020 82.4 24 74.4 24 9999.9 0 999.9 0 6.3
486990 99999 2/1/2020 82 24 74.7 24 9999.9 0 999.9 0 6.1
486980 99999 2/1/2020 82.2 24 75.1 24 9999.9 0 999.9 0 6.1
486990 99999 3/1/2020 82.1 24 75.2 24 9999.9 0 999.9 0 6.2
... ... ... ... ... ... ... ... ... ... ... ...
486990 99999 29/12/2020 79.3 24 73.5 24 9999.9 0 999.9 0 5.9
486980 99999 30/12/2020 81.8 24 74.6 24 9999.9 0 999.9 0 6.1
486990 99999 30/12/2020 81.8 24 72.7 24 9999.9 0 999.9 0 6.2
486980 99999 31/12/2020 81.1 24 75 24 9999.9 0 999.9 0 6.2
486990 99999 31/12/2020 80.4 24 72.9 24 9999.9 0 999.9 0 6.1
我希望数据框由 'wban'
列分隔我希望它看起来像那样,
date_486990 temp_486990 count_temp_486990 dewp_486990 count_dewp_486990 slp_486990 count_slp_486990 stp_486990 count_stp_486990 visib_486990 date_486980 temp_486980 count_temp_486980 dewp_486980 count_dewp_486980 slp_486980 count_slp_486980 stp_486980 count_stp_486980 visib_486980
1/1/2020 82.6 24 73.9 24 9999.9 0 999.9 0 6.2 1/1/2020 82.4 24 74.4 24 9999.9 0 999.9 0 6.3
2/1/2020 82 24 74.7 24 9999.9 0 999.9 0 6.1 2/1/2020 82.2 24 75.1 24 9999.9 0 999.9 0 6.1
..............................
30/12/2020 81.8 24 72.7 24 9999.9 0 999.9 0 6.2 30/12/2020 81.8 24 74.6 24 9999.9 0 999.9 0 6.1
31/12/2020 80.4 24 72.9 24 9999.9 0 999.9 0 6.1 31/12/2020 81.1 24 75 24 9999.9 0 999.9 0 6.2
这里有一张图片方便参考
我知道这有点难看,但基本上我希望 wban 列中的每个唯一值在右侧都有自己的一组列,但与其余数据共享相同的日期。
我该怎么做,我是否必须逆轴旋转或融化或交叉表或其他东西?我不确定使用什么功能或从哪里开始解决这个问题。
有什么想法吗?
我知道路途遥远,
首先我通过 stn
.
然后我运行一个for循环并在日期合并每一帧。
frame = df[df.stn.unique()]
for i in df.stn.unique():
temp = df[df.stn==i]
frame.merge(temp, how='left', on='date')
是否有更短更高效的 pandas 函数来执行此操作?
有些地方不明确,您描述了 wban
用作主元的值,但在提供的数据集中,具有“486990”和“486980”的列是 stn
。对于其余部分,我会认为您想按 stn
进行调整。如果不是这种情况,请更正您的问题。
您可以使用 pandas.DataFrame.pivot
, specify all columns but stn
and wban
as values. Then rework the MultiIndex
as a single index by concatenating the names. Finally, use dropna
删除数据不完整的行(可选)
df2 = df.pivot(index='date',
columns=['stn'],
values=df.columns.drop(['stn', 'wban'])
)
df2.columns = ['%s_%s' % cols for cols in df2.columns]
df2.dropna()
输出:
date_486980 date_486990 temp_486980 temp_486990 count_temp_486980 count_temp_486990 dewp_486980 dewp_486990 count_dewp_486980 count_dewp_486990 slp_486980 slp_486990 count_slp_486980 count_slp_486990 stp_486980 stp_486990 count_stp_486980 count_stp_486990 visib_486980 visib_486990
date
1/1/2020 1/1/2020 1/1/2020 82.4 82.6 24 24 74.4 73.9 24 24 9999.9 9999.9 0 0 999.9 999.9 0 0 6.3 6.2
2/1/2020 2/1/2020 2/1/2020 82.2 82 24 24 75.1 74.7 24 24 9999.9 9999.9 0 0 999.9 999.9 0 0 6.1 6.1
30/12/2020 30/12/2020 30/12/2020 81.8 81.8 24 24 74.6 72.7 24 24 9999.9 9999.9 0 0 999.9 999.9 0 0 6.1 6.2
31/12/2020 31/12/2020 31/12/2020 81.1 80.4 24 24 75 72.9 24 24 9999.9 9999.9 0 0 999.9 999.9 0 0 6.2 6.1