2

我遇到了 pandas pivot_table 函数以及它如何处理 NaN 值的问题。下面是 pandas 如何处理 NaN 的示例:

import pandas as pd

dataframe = pd.DataFrame([[1, 1, 23501, 1000], 
                          [2, 1, 23501, 1000], 
                          [3, None, None, None], 
                          [4, 1, 23501, 1000]], 
                          columns=['A','B' , 
                                   'C', 'D'])

dataframe = dataframe.reset_index().pivot_table(index = ['index', 'A'], columns = ['B'])
print(dataframe)

结果:

                      C            D
B                     1.0          1.0
index A                        
0     1           23501.0       1000.0
1     2           23501.0       1000.0
3     4           23501.0       1000.0

这种方法的问题是 pivot_table 完全删除了填充了 NaN 值的行。我已经看到 pivot_table 有一个 dropna 标志,但是使用时产生的结果很奇怪,并且仍然排除了索引 2 的 NaN 值。

使用 dropna 的结果:

                      C            D
B                     1.0          1.0
index A                        
0     1           23501.0       1000.0
      2               NaN          NaN
      4               NaN          NaN
1     1               NaN          NaN
      2           23501.0       1000.0
      4               NaN          NaN
3     1               NaN          NaN
      2               NaN          NaN
      4           23501.0       1000.0

我查看了这个 github 页面:https ://github.com/pandas-dev/pandas/issues/18030并且在尝试其中一种解决方案时,它为我修改了(我认为)df.groupby(["A", "B"]).agg('first').unstack([1])它给我的结果和刚刚做的一样一个数据透视表。

是否有可能的解决方案使用其他 pandas 函数来保持 nan 值在旋转以创建类似以下内容时存在:

                      C            D
B                     1.0          1.0
index A                         
0     1           23501.0       1000.0
1     2           23501.0       1000.0
2     3           NaN              NaN
3     4           23501.0       1000.0

谢谢您的帮助

4

1 回答 1

2

将其他级别添加到索引,然后添加unstack“B”。这将创建一个NaN我们不想要的关卡,因此我们将其过滤掉。

如果你愿意,你可以使用'Int64''B' 的 dtype,这将保持 np.int64 的水平值,1而不是浮点数。

df.index.name = 'index'  # level will have a name now
# df['B'] = df['B'].astype('Int64') # prevents upcasting
df = df.set_index(['A', 'B'], append=True).unstack(-1)
df = df.loc[:, df.columns.get_level_values('B').notnull()]

               C       D
B            1.0     1.0
index A                 
0     1  23501.0  1000.0
1     2  23501.0  1000.0
2     3      NaN     NaN
3     4  23501.0  1000.0
于 2020-07-10T20:23:01.210 回答