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