大熊猫以不同于循环的方式修改列

时间:2019-09-06 10:19:17

标签: python pandas dataframe

我有一个df:

DF
name1   name2    finalName
AB123   BB123    0
BB113   AB113    0
AB343   AB343    0
CC263   BB263    0
ED633   DD633    0

我需要以这种方式修改finalNameif name1 starts with AB and name2 starts with BB-finalName应该是BB+number,因此在第一种情况下:BB123

if name1 starts with BB and name2 starts with AB-finalName应该是AB+number,因此在第二种情况下:AB123

在其余示例中,finalName应该保持为0。

我写了这段代码:

for row in range(len(DF)):
    if(DF.name1.loc[row][0:2] == 'AB' and DF.name2.loc[row][0:2] == 'BB'):
         DF.finalName[row] = DF.name1[row].replace('AB','BB',1)
    if(DF.name1.loc[row][0:2] == 'BB' and DF.name2.loc[row][0:2] == 'AB'):
         DF.finalName[row] = DF.name1[row].replace('BB','AB',1)

我得到一个Key error,因为我缺少索引(... 69,70,72 ..)。因此,我找到了需要重新索引df的信息。我做到了,一切正常。但是我还发现了一条信息,我不应该循环我的DF。所以我的问题是:

我该如何用Padnas方式进行操作?我是说没有循环?

PS。最终df应该看起来像:

DF
name1   name2    finalName
AB123   BB123    BB123   
BB113   AB113    AB113
AB343   AB343    0
CC263   BB263    0
ED633   DD633    0

3 个答案:

答案 0 :(得分:1)

这是使用series.str.startswith()的一种方法:

c1=df.name1.str.startswith('AB')&df.name2.str.startswith('BB')
c2=df.name1.str.startswith('BB')&df.name2.str.startswith('AB')

df['finalName']=np.where(c1|c2,df.name2,df.finalName)
print(df)

   name1  name2 finalName
0  AB123  BB123     BB123
1  BB113  AB113     AB113
2  AB343  AB343         0
3  CC263  BB263         0
4  ED633  DD633         0

答案 1 :(得分:1)

相反,可以将replaceBB添加到AB Series的值中,而numpy.select的前2个字母不添加:

c

或者:

a = DF.name1.str[:2] 
b = DF.name2.str[:2] 
c = DF.name1.str[2:] 
m1 = (a == 'AB') & (b == 'BB')
m2 = (a == 'BB') & (b == 'AB')

c = DF.name1.str[2:] 
m1 = DF.name1.str.startswith('AB') & DF.name2.str.startswith('BB')
m2 = DF.name1.str.startswith('BB') & DF.name2.str.startswith('AB')

另一种解决方案:

DF['finalName'] = np.select([m1, m2], ['BB' + c, 'AB' + c], DF.finalName)
print (DF)
   name1  name2 finalName
0  AB123  BB123     BB123
1  BB113  AB113     AB113
2  AB343  AB343         0
3  CC263  BB263         0
4  ED633  DD633         0

答案 2 :(得分:1)

您可以使用.apply()这样的方法:

def make_finalName(row):
    if row['name1'].startswith('AB') and row['name2'].startswith('BB'):
        return row['name2']
    if row['name1'].startswith('BB') and row['name2'].startswith('AB'):
        return row['name2']
    return row['finalName']

df['finalName'] = df.apply(lambda row: make_finalName(row), axis=1)

输出如下:

>> print(df)
   name1  name2 finalName
0  AB123  BB123     BB123
1  BB113  AB113     AB113
2  AB343  AB343         0
3  CC263  BB263         0
4  ED633  DD633         0