pandas 如何在透视表中保留NaN?

umuewwlo  于 2023-03-16  发布在  其他
关注(0)|答案(6)|浏览(117)

希望在更改 Dataframe 的形状时保留NaN值。
这两个问题可能是相关的:

但无法使用所提供的答案-我可以以某种方式为np.sum设置一个最小计数吗?

import pandas as pd
import numpy as np
df = pd.DataFrame([['Y1', np.nan], ['Y2', np.nan], ['Y1', 6], ['Y2',8]], columns=['A', 'B'], index=['1988-01-01','1988-01-01', '1988-01-04', '1988-01-04'])
df.index.name = 'Date'
df

pivot_df = pd.pivot_table(df, values='B', index=['Date'], columns=['A'],aggfunc=np.sum)
pivot_df

输出为:

A   Y1  Y2
Date        
1988-01-01  0.0 0.0
1988-01-04  6.0 8.0

并且期望的输出是:

A   Y1  Y2
Date        
1988-01-01  NaN NaN
1988-01-04  6.0 8.0
1aaf6o9v

1aaf6o9v1#

从有用的评论来看,以下解决方案符合我的要求:

pivot_df_2 = pd.pivot_table(df, values='B', index=['Date'], columns=['A'],aggfunc=min, dropna=False)
pivot_df_2

每个插槽的值应该是唯一的,所以用min函数替换sum函数应该不会有什么不同(在我的例子中)

jei2mxaa

jei2mxaa2#

如果没有重复条目,请使用set_index + unstack

df.set_index('A', append=True)['B'].unstack(-1)
A            Y1   Y2
Date
1988-01-01  NaN  NaN
1988-01-04  6.0  8.0

如果有重复项,请将groupbymin_count一起使用

>> df

             A    B
Date
1988-01-01  Y1  NaN
1988-01-01  Y2  NaN
1988-01-04  Y1  6.0
1988-01-04  Y2  8.0
1988-01-01  Y1  NaN
1988-01-01  Y2  NaN
1988-01-04  Y1  6.0
1988-01-04  Y2  8.0
df.set_index('A', append=True).groupby(level=[0, 1])['B'].sum(min_count=1).unstack(-1)
A             Y1    Y2
Date
1988-01-01   NaN   NaN
1988-01-04  12.0  16.0
kkbh8khc

kkbh8khc3#

在本例中,我将通过groupby进行解析:

(df.groupby(['Date', 'A']).B
   .apply(lambda x: np.nan if x.isna().all() else x.sum())
   .unstack('A')
)

输出:

A            Y1   Y2
Date                
1988-01-01  NaN  NaN
1988-01-04  6.0  8.0

如果需要,请将isna().all()更改为isna().any()

a64a0gku

a64a0gku4#

可以对值进行计数,并在为0(或小于预期计数)时丢弃:

pivot_df = pd.pivot_table(df, values='B', index=['Date'], columns=['A'],
                          aggfunc=['sum','count'])

# build the mask from count
mask = (pivot_df.xs('count', axis=1) == 0)   # or ...<min_limit

#build the actual pivot_df from sum
pivot_df = pivot_df.xs('sum', axis=1)

# and reset to NaN when not enough values
pivot_df[mask] = np.nan

它给出了预期结果:

A            Y1   Y2
Date                
1988-01-01  NaN  NaN
1988-01-04  6.0  8.0

当你对一个以上的值求和时,这个方法会给予合理的结果。

pw9qyyiw

pw9qyyiw5#

我还想保留NaN值,还想继续使用pivot_table函数,所以我的解决方案如下:

pivot_df = pd.pivot_table(
    df,
    values='B',
    index=['Date'],
    columns=['A'],
    aggfunc=lambda x: x.sum(min_count=1)
)

The downside is that this is less efficient in terms of computation time.
isr3a4wc

isr3a4wc6#

尝试将'dropna= False'添加到pivot_table函数中?

相关问题