如何将DataFrame列作为python中的行收集到键值对中

时间:2017-03-08 08:05:12

标签: python r pandas dataframe

我正在尝试将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

任何帮助都会非常酷!

4 个答案:

答案 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)

您可以使用renamestackreset_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