我需要合并相似的列并删除重复项(具有相同日期的条目)。数据框:
Albumin C-reactive protein CRP Ferritin Haemoglobin Hb Iron Nancy Index Plasma Platelets Transferrin saturation % Transferrin saturations UCEIS (0 to 8) WCC White Cell Count test_date
0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 12.35 2016-04-17 23:00:00
1 NaN NaN NaN NaN 133.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 2016-04-17 23:00:00
2 NaN NaN NaN NaN NaN NaN NaN NaN NaN 406.0 NaN NaN NaN NaN NaN 2016-04-17 23:00:00
3 NaN NaN NaN NaN NaN NaN NaN NaN NaN 406.0 NaN NaN NaN NaN NaN 2016-04-17 23:00:00
4 NaN 32.2 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 2016-04-17 23:00:00
5 36.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 2016-04-17 23:00:00
6 NaN NaN NaN 99.7 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 2016-04-17 23:00:00
7 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 25.0 NaN NaN NaN NaN 2016-04-17 23:00:00
12 36.0 NaN 32.2 99.7 NaN 133.0 NaN NaN NaN 406.0 NaN 25.0 NaN 12.35 NaN 2016-04-17 23:00:00
14 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 7.0 NaN NaN 2016-04-25 23:00:00
79 34.0 NaN 5.4 55.9 NaN 133.0 NaN NaN NaN 372.0 NaN 28.0 NaN 7.99 NaN 2016-06-12 23:00:00
我需要得到:
Albumin CRP Ferritin Hb Nancy Index Plasma Platelets Transferrin saturations UCEIS (0 to 8) WCC test_date
12 36.0 32.2 99.7 133.0 NaN NaN 406.0 25.0 NaN 12.35 2016-04-17 23:00:00
14 NaN NaN NaN NaN NaN NaN NaN NaN 7.0 NaN 2016-04-25 23:00:00
79 34.0 5.4 55.9 133.0 NaN NaN 372.0 28.0 NaN 7.99 2016-06-12 23:00:00
因此,色谱柱'C反应蛋白'应与'CRP','血红蛋白'与'Hb','转铁蛋白饱和度%'与'转铁蛋白饱和度'合并。
我可以使用 .drop_duplicates()轻松删除重复项,但诀窍不仅是删除具有相同日期的行,而且还要确保同一列中的值是重复的。例如,行'4'处的'C-反应蛋白'具有与'12'行中'CRP'相同的值,此外,它们都具有相同的输入日期。鉴于这一切,我需要只有'CRP'列,其值为32.2,日期为'2016-04-17'(加上其他唯一列)。
修改
有些条目实际上是重复的(完全相同,由于系统故障),例如(最后三行,2016-06-20,索引'803'和'122')。下面的解决方案是否能够删除这些相同的行?
P.S。感谢复制但不完全相同的条目的惊人和通用的解决方案。
Albumin C-reactive protein CRP Ferritin Haemoglobin Hb Iron Nancy Index Plasma Platelets Transferrin saturation % Transferrin saturations UCEIS (0 to 8) WCC White Cell Count setName test_date
735 39.0 NaN 0.4 52.0 NaN 144.0 NaN NaN NaN 197.0 NaN 25.0 NaN 4.88 NaN Bloods 2016-05-31 23:00:00
803 40.0 NaN 0.2 81.0 NaN 147.0 NaN NaN NaN 234.0 NaN 35.0 NaN 8.47 NaN Bloods 2016-06-20 23:00:00
347 NaN NaN NaN NaN NaN NaN NaN NaN 1.0 NaN NaN NaN NaN NaN NaN Research Bloods 2016-06-20 23:00:00
122 40.0 NaN 0.2 81.9 NaN 147.0 NaN NaN NaN 234.0 NaN 35.0 NaN 8.47 NaN Bloods 2016-06-20 23:00:00
答案 0 :(得分:2)
我认为您需要rename
dict
列d = {'C-reactive protein':'CRP', 'Hemoglobin':'Hb',
'Transferrin saturation %':'Transferrin saturations'}
df = df.groupby('test_date').max().rename(columns=d).groupby(axis=1, level=0).max()
print (df)
Albumin CRP Ferritin Haemoglobin Hb Iron \
test_date
2016-04-17 23:00:00 36.0 32.2 99.7 133.0 133.0 NaN
2016-04-25 23:00:00 NaN NaN NaN NaN NaN NaN
2016-06-12 23:00:00 34.0 5.4 55.9 NaN 133.0 NaN
Nancy Index Plasma Platelets Transferrin saturations \
test_date
2016-04-17 23:00:00 NaN NaN 406.0 25.0
2016-04-25 23:00:00 NaN NaN NaN NaN
2016-06-12 23:00:00 NaN NaN 372.0 28.0
UCEIS (0 to 8) WCC White Cell Count
test_date
2016-04-17 23:00:00 NaN 12.35 12.35
2016-04-25 23:00:00 7.0 NaN NaN
2016-06-12 23:00:00 NaN 7.99 NaN
:
DataFrame
更一般的解决方案是groupby
重新整形,删除重复项,然后再创建d = {'C-reactive protein':'CRP', 'Hemoglobin':'Hb',
'Transferrin saturation %':'Transferrin saturations'}
df = df.rename(columns=d).groupby(axis=1, level=0).max()
df = pd.melt(df, id_vars='test_date').dropna(subset=['value']).drop_duplicates()
df = df.groupby(['test_date','variable'])['value'] \
.apply(lambda x: pd.Series(x.values)) \
.unstack(1) \
.reset_index(level=1, drop=True) \
.reset_index() \
.rename_axis(None,axis=1)
print (df)
test_date Albumin CRP Ferritin Hb Platelets \
0 2016-04-17 23:00:00 1000.0 32.2 99.7 1000.0 406.0
1 2016-04-17 23:00:00 36.0 NaN NaN 133.0 NaN
2 2016-04-25 23:00:00 NaN NaN NaN NaN NaN
3 2016-06-12 23:00:00 34.0 5.4 55.9 133.0 372.0
Transferrin saturations UCEIS (0 to 8) WCC White Cell Count
0 25.0 NaN 12.35 12.35
1 NaN NaN NaN NaN
2 NaN 7.0 NaN NaN
3 28.0 NaN 7.99 NaN
:
public class Emp
{
public int Id { get; set; }
public string Name { get; set; }
public int Amount { get; set; }
public IList<Emp> GetMasterDetails()
{
IList<Emp> masterList = new List<Emp>
{
new Emp { Id = 952491, Name = "Z005HY11", Amount = 500 },
new Emp { Id = 952491, Name = "Z005H717", Amount = 500 },
new Emp { Id = 1191676, Name = "Z005H717", Amount = 400 }
};
return masterList;
}
public IList<Emp> GetNonMasterDetails()
{
IList<Emp> nonMasterList = new List<Emp>
{
new Emp { Id = 952491, Name = "Z005H717", Amount = 500 },
new Emp { Id = 1191676, Name = "Z005H717", Amount = 500 },
new Emp { Id = 1227997, Name = "Z005HY11", Amount = 400 }
};
return nonMasterList;
}
}
Emp obj = new Emp();
IList<Emp> masterList = obj.GetMasterDetails();
IList<Emp> nonMasterList = obj.GetNonMasterDetails();
var first = masterList.Where(p => !nonMasterList.Any(l => p.Id == l.Id || p.Name ==l.Name)).ToList();
var second = nonMasterList.Where(p => !masterList.Any(l => p.Id == l.Id || p.Name == l.Name)).ToList();
答案 1 :(得分:1)
@jezrael所说的是,如果您遇到以下情况:
Albumin C-reactive protein CRP test_date
0 NaN NaN 32 2016-04-17 23:00:00
1 NaN 8.0 NaN 2016-04-17 23:00:00
然后他的方法将删除8.0读数并仅保留32(这是因为他分两步(或3?),在这一行:df = df.groupby('test_date').max().rename(columns=d).groupby(axis=1, level=0).max()
df = df.groupby('test_date').max() # selects max of each column
# while collapsing 'test_date'
对于我的截断示例,它将给出:
Albumin C-reactive protein CRP test_date
0 NaN 8.0 32 2016-04-17 23:00:00
然后重命名.rename(columns=d)
给予:
Albumin CRP CRP test_date
0 NaN 8.0 32 2016-04-17 23:00:00
然后.groupby(axis=1, level=0).max()
沿着行(而不是向下列)分组,它们给出了:
Albumin CRP test_date
0 NaN 32 2016-04-17 23:00:00
这是您丢失数据的最大风险。
我会先将原始数据分成两个帧
df1 = df[["C-reactive protein","Haemoglobin", ...]]
df2 = df[["CRP", "Hb"]]
# then rename
df2 = df2.rename(columns={"CRP":"C-reactive protein", "Hb":"Haemoglobin", ...})
# use concat to stack them on one another
df3 = pd.concat([df1, df2]) # i've run out of names
df3 = df3.drop_duplicates() # perhaps also drop NAs?
但只有在同一天有同一个测试的多个非重复条目时才需要这样做。