我正在尝试将pandas DataFrame列收集到一个键值对中,并将其列为python中的一行。如果我们以下面的DataFrame为例,我想从这里开始:
import pandas as pd
from collections import OrderedDict
df = pd.DataFrame({'value_2016': [200],
'value_2017': [300],
'value_2018': [float('NaN')]})
print(df)
value_2016 value_2017 value_2018
0 200 300 NaN
为:
df_result = pd.DataFrame(OrderedDict({'year': [2016, 2017],
'value': [200, 300]}))
print(df_result)
year value
0 2016 200
1 2017 300
如果你熟悉R,那么等价物将是这样的:
require("plyr"); require("dplyr"); require(tidyr)
df <- data.frame(value_2016 = 200,
value_2017 = 300,
value_2018 = NA)
df %>%
gather(year, value, value_2016:value_2018) %>%
mutate(year = gsub(x = .$year, replacement = "", "value_")) %>%
na.exclude
year value
1 2016 200
2 2017 300
任何帮助都会非常酷!
答案 0 :(得分:2)
另一种使用熔体的解决方案:
ipdb> pd.melt(df.rename(columns=lambda x: x.split('_')[-1]), var_name="year", value_name="value").dropna()
year value
0 2016 200.0
1 2017 300.0
答案 1 :(得分:1)
您可以split
创建MultiIndex
,然后按stack
重新塑造:
df.columns = df.columns.str.split('_', expand=True)
df = df.stack().reset_index(level=0, drop=True).rename_axis('year').reset_index()
#if necessary convert float to int
df.value = df.value.astype(int)
print (df)
year value
0 2016 200
1 2017 300
如果要使用DataFrame
构造函数,请使用get_level_values
:
df.columns = df.columns.str.split('_', expand=True)
df = df.stack()
df_result = pd.DataFrame(OrderedDict({'year': df.index.get_level_values(1),
'value': df['value'].astype(int).values}))
print(df_result)
year value
0 2016 200
1 2017 300
答案 2 :(得分:0)
您可以使用rename
,stack
和reset_index
In [4912]: (df.rename(columns=lambda x: x.split('_')[-1]).stack()
.reset_index(level=0, drop=True)
.rename_axis('year')
.reset_index(name='value'))
Out[4912]:
year value
0 2016 200.0
1 2017 300.0
答案 3 :(得分:0)
或者使用datar
:
>>> from datar.all import f, NA, tribble, pivot_longer, everything, drop_na
>>>
>>> df = tribble(
... f.value_2016, f.value_2017, f.value_2018,
... 200, 300, NA
... )
>>> df
value_2016 value_2017 value_2018
<int64> <int64> <float64>
0 200 300 NaN
>>>
>>> pivot_longer(df, everything()) >> drop_na()
name value
<object> <float64>
0 value_2016 200.0
1 value_2017 300.0