Python 按组中的数字填充组中的NaN值

Python 按组中的数字填充组中的NaN值,python,python-3.x,pandas,Python,Python 3.x,Pandas,我有一个数据帧,比如 Groups NAME VALUES G1 A 1 G1 B 2 G1 C 3 G1 C 3 G2 D NaN G2 E NaN G2 D NaN G3 F NaN G3 G NaN G3 H NaN G4 I 8 G4 I 8 G4 J 89 G4 K 65 我只想用

我有一个数据帧,比如

Groups NAME VALUES 
G1     A    1
G1     B    2
G1     C    3
G1     C    3
G2     D    NaN
G2     E    NaN
G2     D    NaN 
G3     F    NaN
G3     G    NaN 
G3     H    NaN 
G4     I    8
G4     I    8
G4     J    89
G4     K    65 
我只想用NaN值填充组,并为每个不同的名称添加一个数字,从1开始

那么我应该得到:

Groups NAME VALUES 
G1     A    1
G1     B    2
G1     C    3
G1     C    3
G2     D    1
G2     E    2
G2     D    1
G3     F    1
G3     G    2
G3     H    3
G4     I    8
G4     I    8
G4     J    89
G4     K    65 
数据如下:

{'Groups': {0: 'G1', 1: 'G1', 2: 'G1', 3: 'G1', 4: 'G2', 5: 'G2', 6: 'G2', 7: 'G3', 8: 'G3', 9: 'G3', 10: 'G4', 11: 'G4', 12: 'G4', 13: 'G4'}, 'NAME': {0: 'A', 1: 'B', 2: 'C', 3: 'C', 4: 'D', 5: 'E', 6: 'D', 7: 'F', 8: 'G', 9: 'H', 10: 'I', 11: 'I', 12: 'J', 13: 'K'}, 'VALUES': {0: 1.0, 1: 2.0, 2: 3.0, 3: 3.0, 4: nan, 5: nan, 6: nan, 7: nan, 8: nan, 9: nan, 10: 8.0, 11: 8.0, 12: 89.0, 13: 65.0}}

我将首先为NaN行选择唯一的名称:

m = df['VALUES'].isna()
names = df.loc[m, 'NAME'].unique()
然后为以下各项创建映射:

mapping = dict(zip(names, list(range(1,len(names)+1))))
然后用映射填充NaN行的值:

df.loc[m, 'VALUES'] = df.loc[m, 'NAMES'].map(mapping)
更新以根据我从您的评论中了解到的组填充值:

因此,我们再次选择具有NaN值的行。现在我们做一个groupby并使用transform保留原始的df索引。要添加列表,我们需要知道组的长度。因此,我添加了大小列

df = pd.DataFrame({'Groups': {0: 'G1', 1: 'G1', 2: 'G1', 3: 'G1', 4: 'G2', 5: 'G2', 6: 'G2', 7: 'G3', 8: 'G3', 9: 'G3', 10: 'G4', 11: 'G4', 12: 'G4', 13: 'G4'}, 'NAME': {0: 'A', 1: 'B', 2: 'C', 3: 'C', 4: 'D', 5: 'E', 6: 'D', 7: 'F', 8: 'G', 9: 'H', 10: 'I', 11: 'I', 12: 'J', 13: 'K'}, 'VALUES': {0: 1.0, 1: 2.0, 2: 3.0, 3: 3.0, 4: np.nan, 5: np.nan, 6: np.nan, 7: np.nan, 8: np.nan, 9: np.nan, 10: 8.0, 11: 8.0, 12: 89.0, 13: 65.0}})
    sizes = df.groupby(['Groups']).size()
    df['Size']=df['Groups'].map(sizes)
    m = df['VALUES'].isna()
下一步,您需要重复出现Group和NAME,因此Group和NAME上的groupby具有相同的编号,如G2和D=>因此,我们选择此类行的第一次出现,并将其映射到Group和NAME的组合:

df.loc[m, 'VALUES_new']  = df.loc[m].groupby(['Groups'])['Size'].transform(lambda x:list(range(1,len(x)+1)))
mapping = df.loc[m].groupby(['Groups', 'NAME'])['VALUES_new'].first().copy()
df.set_index(['Groups', 'NAME'], inplace=True)
m = df['VALUES'].isna()
df.loc[m,'VALUES'] = df.loc[m].index.map(mapping)
df.reset_index(inplace=True)
df.drop(columns=['Size', 'VALUES_new'], inplace=True)
df['VALUES']=df['VALUES'].astype(int)
为了了解各个组的情况,您可以运行以下命令:

df = pd.DataFrame({'Groups': {0: 'G1', 1: 'G1', 2: 'G1', 3: 'G1', 4: 'G2', 5: 'G2', 6: 'G2', 7: 'G3', 8: 'G3', 9: 'G3', 10: 'G4', 11: 'G4', 12: 'G4', 13: 'G4'}, 'NAME': {0: 'A', 1: 'B', 2: 'C', 3: 'C', 4: 'D', 5: 'E', 6: 'D', 7: 'F', 8: 'G', 9: 'H', 10: 'I', 11: 'I', 12: 'J', 13: 'K'}, 'VALUES': {0: 1.0, 1: 2.0, 2: 3.0, 3: 3.0, 4: np.nan, 5: np.nan, 6: np.nan, 7: np.nan, 8: np.nan, 9: np.nan, 10: 8.0, 11: 8.0, 12: 89.0, 13: 65.0}})
m = df['VALUES'].isna()
grouped = df.loc[m].groupby(['Groups']) #groupby object

for group in grouped:
    print(group[0]) # str with the group name
    dfgroup = group[1] # dataframe of the group
    values = list(range(1,len(dfgroup)+1))
    dfgroup['VALUES'] = values
    print(dfgroup)

尝试将每个组的名称转换为类别类型,然后获取cat代码并添加1:

将numpy作为np导入 作为pd进口熊猫 d={'Groups':{0:'G1',1:'G1',2:'G1',3:'G1',4:'G2',5:'G2',6:'G2', 7:'G3',8:'G3',9:'G3',10:'G4',11:'G4',12:'G4', 13:‘G4’}, 'NAME':{0:A',1:B',2:C',3:C',4:D',5:E',6:D',7:F', 8:G',9:H',10:I',11:I',12:J',13:K'}, 'VALUES':{0:1.0,1:2.0,2:3.0,3:3.0,4:np.nan,5:np.nan, 6:np.nan,7:np.nan,8:np.nan,9:np.nan,10:8.0, 11: 8.0, 12: 89.0, 13: 65.0}} df=pd.DataFramed 值为NaN的位置的掩码 m=df['VALUES'].isna 按“组”分组 df.loc[m,'VALUES']=df[m].groupby'Groups',as_index=False,sort=False.apply 将“名称”转换为类别并获取cat代码 添加1以1而不是0开头 lambda g:g['NAME'].aType'category'。类别代码+1 价值观 转换为int以匹配输出 df['VALUES']=df['VALUES'].astypeint printdf df:


您好,事实上,代码有误,它对数字求和,但每个组的第一个数字应该始终为1。。。例如,G3-F得到的是3而不是1。好吧,我现在更理解你的问题了,我假设你想用名字来填充。我已经更新了解决方案以供小组填写。希望这是清楚的!
   Groups NAME  VALUES
0      G1    A       1
1      G1    B       2
2      G1    C       3
3      G1    C       3
4      G2    D       1
5      G2    E       2
6      G2    D       1
7      G3    F       1
8      G3    G       2
9      G3    H       3
10     G4    I       8
11     G4    I       8
12     G4    J      89
13     G4    K      65