我有一个大约2000行的多列df。 df看起来像这样:
site le_cell le_id ca ca_id
1 101 1011 1 NAN NAN
2 101 1012 2 NAN NAN
3 101 1013 3 NAN NAN
4 110 1101 1 2 11
5 110 1102 2 2 12
6 110 1103 3 2 13
7 110 1104 11 2 1
8 110 1105 12 2 2
9 110 1106 13 2 3
这是问题所在。我需要创建一个名为'part_id'的新列,值为: Groupby'site',如果没有'ca'(ca = NAN),则'part_id'等于le_id(part_id = le_id)。如果有'ca',则读'ca_id'和'part_id'的值将是1,2,3.1和11 = 1,2和12 = 2,3和13 = 3。 期望的输出:
site le_cell le_id ca ca_id part_id
1 101 1011 1 NAN NAN 1
2 101 1012 2 NAN NAN 2
3 101 1013 3 NAN NAN 3
4 110 1101 1 2 11 1
5 110 1102 2 2 12 2
6 110 1103 3 2 13 3
7 110 1104 11 2 1 1
8 110 1105 12 2 2 2
9 110 1106 13 2 3 3
简单来说,a不能只将所有le_id值从11,12,13转换为1,2,3。所以我需要通过'ca'并与'le_cell'匹配相同的'le_id'就像那个'ca_id'。
我尝试过转换为dict,但它不会很好,真的不知道如何开始。 至少,给我一些提示。
答案 0 :(得分:1)
我认为您可以创建布尔掩码,然后通过numpy.where
将值添加到列:
#if need check if all values per group are NaN
a = df['ca'].isnull().groupby(df['site']).all()
m = df['site'].isin(a.index[a])
#if need check if column ca is NaN
#m= df['ca'].isnull()
d = {11:1,12:2,13:3}
df['part_id'] = np.where(m, df['le_id'], df['ca_id'].replace(d))
print (df)
site le_cell le_id ca ca_id part_id
1 101 1011 1 NaN 0 1
2 101 1012 2 NaN 0 2
3 101 1013 3 NaN 0 3
4 110 1101 1 2.0 11 1
5 110 1102 2 2.0 12 2
6 110 1103 3 2.0 13 3
7 110 1104 11 2.0 1 1
8 110 1105 12 2.0 2 2
9 110 1106 13 2.0 3 3
答案 1 :(得分:1)
您可以定义一个映射器并使用apply
与lambda
一起根据您的条件分配值:
mapper = {1: 1,
11: 1,
2: 2,
12: 2,
3: 3,
13: 3}
df['part_id'] = df.apply(lambda row: row.le_id if np.isnan(row.ca) else mapper[row.ca_id], axis=1)
ca ca_id le_cell le_id site part_id
0 NaN NaN 1011 1 101 1.0
1 NaN NaN 1012 2 101 2.0
2 NaN NaN 1013 3 101 3.0
3 2.0 11.0 1101 1 110 1.0
4 2.0 12.0 1102 2 110 2.0
5 2.0 13.0 1103 3 110 3.0
6 2.0 1.0 1104 11 110 1.0
7 2.0 2.0 1105 12 110 2.0
8 2.0 3.0 1106 13 110 3.0
希望您不要介意float
,但如果您这样做是转换:
df['part_id'] = df['part_id'].astype(int)