python - Pandas :如何 groupby/pivot 保留 NaNs?将 float 转换为 str 然后再转换回 float 有效但看起来很复杂

标签 python pandas group-by nan

我正在跟踪某个事件发生在哪个“月份”。如果没有,则“月”字段为 NaN。起始表如下所示:

+-------+----------+---------+
| Month | Category | Balance |
+-------+----------+---------+
| 1     | a        |     100 |
| nan   | a        |     300 |
| 2     | a        |     200 |
+-------+----------+---------+

我正在尝试构建这样的交叉表:

+-------+----------------------------------+
| Month | Category a - cumulative % amount |
+-------+----------------------------------+
|     1 |                             0.16 |
|     2 |                             0.50 |
+-------+----------------------------------+

在第 1 个月,事件发生了 100/600,即 16% 在第 2 个月,事件累计发生了 (100 + 200)/600 = 50%,其中 100 发生在第 1 个月,200 发生在第 2 个月。

我的问题是 NaN。 Pandas 自动从任何 groupby/pivot/crosstab 中删除 NaN。我可以将月份字段转换为字符串,以便对其进行分组不会删除 NaN,但是 pandas 然后按月份排序,就好像它是一个字符串一样,即它会排序:10、48、5、6。

有什么建议吗?

以下工作但似乎非常复杂:

  • 将“月”转换为字符串
  • 做一个交叉表
  • 将“月”转换回 float (我可以不将索引移动到列,然后将列返回索引吗?)
  • 重新排序
  • 射精

代码:

import numpy as np
import pandas as pd

df = pd.DataFrame()
mylen = int(10e3)
df['ix'] = np.arange(0,mylen)
df['amount'] = np.random.uniform(10e3,20e3,mylen)
df['category'] = np.where( df['ix'] <=4000, 'a','b' )
df['month'] = np.random.uniform(3,48,mylen)
df['month'] = np.where( df['ix'] <=1000, np.nan, df['month'] )
df['month rounded'] = np.ceil(df['month'])

ct = pd.crosstab(df['month rounded'].astype(str) , df['category'], \
                 values = df['amount'] ,aggfunc = 'sum', margins = True ,\
                     normalize = 'columns', dropna = False)
    
# the index is 'month rounded'
ct = ct.reset_index()
ct['month rounded'] = ct['month rounded'].astype('float32')
ct = ct.sort_values('month rounded')
ct = ct.set_index('month rounded')
ct2 = ct.cumsum (axis = 0)

最佳答案

使用:

new_df = df.assign(cumulative=df['Balance'].mask(df['Month'].isna())
                                           .groupby(df['Category'])
                                           .cumsum()
                                           .div(df.groupby('Category')['Balance']
                                                  .transform('sum'))).dropna()
print(new_df)
   Month Category  Balance  cumulative
0    1.0        a      100    0.166667
2    2.0        a      200    0.500000

如果您想为每个类别创建一个DataFrame,您可以创建一个字典:

df_category = {i:group for i,group in new_df.groupby('Category')}

关于python - Pandas :如何 groupby/pivot 保留 NaNs?将 float 转换为 str 然后再转换回 float 有效但看起来很复杂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60159973/

相关文章:

python - 使用 python 控制应用程序

列表中项目的Python索引没有错误?

python - 在将总行附加到数据框后删除 Pandas 数据框索引的名称

python - pandas:如何进行多个 groupby-apply 操作

sql - Oracle 仅按一列分组

python - Pandas GroupBy 对同一 DataFrame 的子集

python - 如何找到以 &lt;!-- 开头的 HTML 注释的第一个实例? (Python)

Python - 使用 xlsxwriter 创建依赖下拉列表

python - 使用 pandas 数据框填充 flet 数据表

python - NumPy - 最高平均值的索引