我有下表:
name a0 a1 type val
0 name1 1 0 AB 100
1 name1 2 0 AB 105
2 name2 1 2 BB 110
3 name3 1 0 AN 120
我想这样做。
对于每种类型,我看到类型名称中不包含相同的2个字母,我想复制该行并交换a0和a1列以及类型列的字母。因此,我的结果将是:
name a0 a1 type val
0 name1 1 0 AB 100
1 name1 0 1 BA 100
2 name1 2 0 AB 105
3 name1 0 2 BA 105
4 name2 1 2 BB 110
5 name3 1 0 AN 120
6 name3 0 1 NA 120
请注意,例如,对于相同的名称,我们可以具有相同的类型,但a0和a1(以及val)不同。
因此,我们可以像原始表的前两行一样使用name1并键入AB。
我尝试过:
df1 = pd.DataFrame({'name':['name1', 'name1', 'name2', 'name3'], 'a0':[1, 2, 1, 1], 'a1':[0, 0, 2, 0], 'type':['AB', 'AB', 'BB', 'AN'], 'val':[100,105, 110, 120]})
for idx in df1.index:
a1 = df1.loc[idx, 'a0']
a0 = df1.loc[idx, 'a1']
val = df1.loc[idx, 'val']
name = df1.loc[idx, 'name']
if df1.loc[idx, 'type'] == 'AB':
new_type = 'BA'
elif df1.loc[idx, 'type'] == 'AN':
new_type = 'NA'
row = pd.DataFrame({'name':name, 'a0':a0 , 'a1':a1 , 'type':new_type, 'val':val}, index=np.arange(idx))
df1 = df1.append(row, ignore_index=False)
df1 = df1.sort_index().reset_index(drop=True)
但是它给了我
name a0 a1 type val
0 name1 1 0 AB 100
1 name1 2 0 BA 105
2 name1 0 2 BA 105
3 name1 2 0 BA 105
4 name1 0 2 BA 105
5 name1 2 0 BA 105
6 name1 0 2 BA 105
7 name1 2 0 AB 105
8 name2 1 2 BB 110
9 name3 1 0 AN 120
答案 0 :(得分:3)
首先创建掩码以标识具有2个不同字母的值,然后通过DataFrame.assign
创建新的DataFrame,在列中交换值,连接在一起并按索引排序,最后创建默认索引值:
mask = df['type'].apply(set).str.len() == 2
df1 = df[mask].assign(type=lambda x: df['type'].str[1] + df['type'].str[0])
df1[['a0','a1']] = df1[['a1','a0']].to_numpy()
#pandas below
#df1[['a0','a1']] = df1[['a1','a0']].values
df = pd.concat([df, df1]).sort_index().reset_index(drop=True)
print (df)
name a0 a1 type val
0 name1 1 0 AB 100
1 name1 0 1 BA 100
2 name1 2 0 AB 105
3 name1 0 2 BA 105
4 name2 1 2 BB 110
5 name3 1 0 AN 120
6 name3 0 1 NA 120
答案 1 :(得分:2)
您可以使用:
def myfunc(x):
x['type']=x['type'][::-1]
x[['a0','a1']]=x[['a1','a0']].values
return x
m=df.type.apply(set).str.len().gt(1)
pd.concat([df,df.loc[m].apply(myfunc,axis=1)],ignore_index=True).sort_values(['name','val'])
name a0 a1 type val
0 name1 1 0 AB 100
4 name1 0 1 BA 100
1 name1 2 0 AB 105
5 name1 0 2 BA 105
2 name2 1 2 BB 110
3 name3 1 0 AN 120
6 name3 0 1 NA 120