如何在pandas中填充特定组的缺失值?

ctzwtxfj  于 2023-09-29  发布在  其他
关注(0)|答案(3)|浏览(101)

我有以下pandas dataframe:

df = pd.DataFrame({'Year': [2020, 2021, 2022, 2022, 2018, 2019, 2020, 2021],
                   'Cat1': ['level1', 'level1', 'level1', 'level1', 'level2', 'level2', 'level2', 'level2'],
                   'Cat2': ['sublevel1', 'sublevel1', 'sublevel1', 'sublevel1', 'sublevel2', 'sublevel2', 'sublevel2', 'sublevel2'],
                   'value': [1, 2, 3, 4, 5, 6, 7, 8]})

   Year    Cat1       Cat2  value
0  2020  level1  sublevel1      1
1  2021  level1  sublevel1      2
2  2022  level1  sublevel1      3
3  2022  level1  sublevel1      4
4  2018  level2  sublevel2      5
5  2019  level2  sublevel2      6
6  2020  level2  sublevel2      7
7  2021  level2  sublevel2      8

我想在列'Year'中取唯一值,并复制Cat1和Cat2的值,将结果值填充为0,结果为:

Year    Cat1       Cat2  value
0   2018  level1  sublevel1      0
1   2019  level1  sublevel1      0
2   2020  level1  sublevel1      1
3   2021  level1  sublevel1      2
4   2022  level1  sublevel1      3
5   2022  level1  sublevel1      4
6   2018  level2  sublevel2      5
7   2019  level2  sublevel2      6
8   2020  level2  sublevel2      7
9   2021  level2  sublevel2      8
10  2022  level2  sublevel2      0

我考虑过使用groupby(),但我不确定它是否有效,因为我想保留跨Year有重复的行,例如索引2和3上的行。我还尝试了将Year设置为索引,并使用set_index()和唯一的Year值来填充它,但这似乎对有重复的值不起作用。
使用groupby()的其他尝试导致了我不想要的值。返回level1和sublevel2的行,这是我想避免的。
任何帮助非常感谢。

6ojccjat

6ojccjat1#

我将使用set操作(和groupby.agg)来识别每组缺失的年份,然后手工制作缺失的行,并将它们返回到原始数据:

# all existing years
# this could also be manually defined: years = set(range(2028, 2023))
years = set(df['Year'])

# identify missing years per group
# create new rows
missing = (df
   .groupby(['Cat1', 'Cat2'])['Year'].agg(set).rsub(years)
   .explode().reset_index(name='Year')
   .assign(value=0)
)

# concat to original
out = (pd.concat([df, missing])
         .sort_values(by=['Cat1', 'Cat2', 'Year'], ignore_index=True)
      )

输出量:

Year    Cat1       Cat2  value
0   2018  level1  sublevel1      0
1   2019  level1  sublevel1      0
2   2020  level1  sublevel1      1
3   2021  level1  sublevel1      2
4   2022  level1  sublevel1      3
5   2022  level1  sublevel1      4
6   2018  level2  sublevel2      5
7   2019  level2  sublevel2      6
8   2020  level2  sublevel2      7
9   2021  level2  sublevel2      8
10  2022  level2  sublevel2      0
lokaqttq

lokaqttq2#

一个选项是完整的:

# pip install pyjanitor
import pandas as pd
import janitor 
(df
# you can skip sort if you are not fuzzy about order
.complete('Year', ('Cat1','Cat2'),sort=True) 
.fillna({'value':0})
.astype({'value':int})
)   
    Year    Cat1       Cat2  value
0   2018  level1  sublevel1      0
1   2018  level2  sublevel2      5
2   2019  level1  sublevel1      0
3   2019  level2  sublevel2      6
4   2020  level1  sublevel1      1
5   2020  level2  sublevel2      7
6   2021  level1  sublevel1      2
7   2021  level2  sublevel2      8
8   2022  level1  sublevel1      3
9   2022  level1  sublevel1      4
10  2022  level2  sublevel2      0

注意Cat列是如何 Package 在一个元组中的-函数将它们一起处理;你会得到一个不同的输出,如果它是这样的-> 'Year', 'Cat1','Cat2'

9udxz4iz

9udxz4iz3#

通过创建一个包含“Year”列的唯一值的新DataFrame,然后将其与原始DataFrame合并,可以获得所需的结果

import pandas as pd

df = pd.DataFrame({'Year': [2020, 2021, 2022, 2022, 2018, 2019, 2020, 2021],
                   'Cat1': ['level1', 'level1', 'level1', 'level1', 'level2', 'level2', 'level2', 'level2'],
                   'Cat2': ['sublevel1', 'sublevel1', 'sublevel1', 'sublevel1', 'sublevel2', 'sublevel2', 'sublevel2', 'sublevel2'],
                   'value': [1, 2, 3, 4, 5, 6, 7, 8]})

# Create a DataFrame with unique 'Year' values
unique_years = pd.DataFrame({'Year': df['Year'].unique()})

# Merge the unique_years DataFrame with the original DataFrame using a left join
result = unique_years.merge(df, on=['Year', 'Cat1', 'Cat2'], how='left').fillna({'value': 0})

print(result)

这段代码会给予你想要的输出:

Year    Cat1       Cat2  value
0   2020  level1  sublevel1      1.0
1   2021  level1  sublevel1      2.0
2   2022  level1  sublevel1      3.0
3   2018  level1  sublevel1      0.0
4   2019  level1  sublevel1      0.0
5   2018  level2  sublevel2      5.0
6   2019  level2  sublevel2      6.0
7   2020  level2  sublevel2      7.0
8   2021  level2  sublevel2      8.0

相关问题