如何在某些条件下重命名pandas数据帧中的列值

时间:2016-02-20 11:15:14

标签: python pandas dataframe cumsum

我有一个像这样的pandas数据框:

 order_id  buyer_id  phone_no
      611      261  9920570003
      681      261  9321613595
      707      261  9768270700
      707      261  9768270700
      707      261  9768270700
      708      261  9820895896
      710      261  7208615775
      710      261  7208615775
      710      261  7208615775
      711      261  9920986486
      800      234    Null
      801      256    Null
      803      289    Null

我必须按如下方式替换buyer_id列:

   order_id   buyer_id   phone_no
      611      261_01  9920570003
      681      261_02  9321613595
      707      261_03  9768270700
      707      261_03  9768270700
      707      261_03  9768270700
      708      261_04  9820895896
      710      261_05  7208615775
      710      261_05  7208615775
      710      261_05  7208615775
      711      261_06  9920986486
      800       234       Null
      801       256       Null
      803       289       Null

因此,如果手机不相同,则应将其视为同一买家,否则应将新系列添加至261.我只想重命名261 buyer_id,其他行应相同。因为我将来自电话的订单视为261

我可以使用以下代码在261 buyer_id中添加系列:

for i in range((len(phone_orders):
    print '261_%d' %i
    segments_data['buyer_id']

phone_orders包含所有电话订单。

但我没有得到如何用期望的输出替换buyer_id

df['buyer_id'] = '261_' + (df['phone_no'] !=      
df['phone_no'].shift()).cumsum().map("{:02}".format)


  buyer_id    phone_no
  261_01  9920570003
  261_02  9321613595
  261_03  9768270700
  261_03  9768270700
  261_03  9768270700
  261_04  9820895896
  261_05  7208615775
  261_05  7208615775
  261_05  7208615775
  261_06  9920986486
  261_07  9768270700
  261_07  9768270700
  261_07  9768270700
  261_08  9820895896
  261_09  7208615775
  261_09  7208615775
  261_09  7208615775

所以7208615775 phone_no应为261_05,但它正在提供261_09

2 个答案:

答案 0 :(得分:3)

原始问题

首先找到唯一的电话号码并创建ID:

id_map = {k: v for v, k in enumerate(df.phone_no.unique(), 1)}

现在,抛出所有条目,将它们添加到相应的电话号码:

df.buyer_id = df.apply(lambda x: '{}_{:02d}'.format(x.buyer_id, id_map[x.phone_no]), axis=1)

结果:

   order_id buyer_id    phone_no
0       611   261_01  9920570003
1       681   261_02  9321613595
2       707   261_03  9768270700
3       707   261_03  9768270700
4       707   261_03  9768270700
5       708   261_04  9820895896
6       710   261_05  7208615775
7       710   261_05  7208615775
8       710   261_05  7208615775
9       711   261_06  9920986486

仅适用于买方ID 261

id_map = {k: v for v, k in enumerate(df[df.buyer_id==261].phone_no.unique(), 1) }

def make_buyer_id(x):
    try:
        return '{}_{:02d}'.format(x.buyer_id, id_map[x.phone_no])
    except KeyError:
        return x.buyer_id

df.buyer_id = df.apply(make_buyer_id, axis=1)

结果:

    order_id buyer_id    phone_no
0        611   261_01  9920570003
1        681   261_02  9321613595
2        707   261_03  9768270700
3        707   261_03  9768270700
4        707   261_03  9768270700
5        708   261_04  9820895896
6        710   261_05  7208615775
7        710   261_05  7208615775
8        710   261_05  7208615775
9        711   261_06  9920986486
10       800      234        Null
11       801      256        Null
12       803      289        Null

答案 1 :(得分:2)

您可以使用astype将列buyer_id转换为stringshiftcumsum,然后map

df['buyer_id']=df['buyer_id'].astype(str) + '_' + (df['phone_no'] != df['phone_no'].shift())
                                                                                   .cumsum()
                                                                        .map("{:02}".format)
print df
   order_id buyer_id    phone_no
0       611   261_01  9920570003
1       681   261_02  9321613595
2       707   261_03  9768270700
3       707   261_03  9768270700
4       707   261_03  9768270700
5       708   261_04  9820895896
6       710   261_05  7208615775
7       710   261_05  7208615775
8       710   261_05  7208615775
9       711   261_06  9920986486

说明:

print (df['phone_no'] != df['phone_no'].shift())
0     True
1     True
2     True
3    False
4    False
5     True
6     True
7    False
8    False
9     True
Name: phone_no, dtype: bool
print (df['phone_no'] != df['phone_no'].shift()).cumsum()
0    1
1    2
2    3
3    3
4    3
5    4
6    5
7    5
8    5
9    6
Name: phone_no, dtype: int32
print (df['phone_no'] != df['phone_no'].shift()).cumsum().map("{:02}".format)
0    01
1    02
2    03
3    03
4    03
5    04
6    05
7    05
8    05
9    06
Name: phone_no, dtype: object

编辑:

如果您希望列261中的过滤器值为buyer_id,则可以使用loc过滤它们:

print df.loc[df['buyer_id'] == 261, 'buyer_id']
0    261
1    261
2    261
3    261
4    261
5    261
6    261
7    261
8    261
9    261
Name: buyer_id, dtype: int64

df.loc[df['buyer_id'] == 261, 'buyer_id'] =  df['buyer_id'].astype(str) + '_' + (df['phone_no'] != df['phone_no'].shift()).cumsum().map("{:02}".format)
print df
    order_id buyer_id    phone_no
0        611   261_01  9920570003
1        681   261_02  9321613595
2        707   261_03  9768270700
3        707   261_03  9768270700
4        707   261_03  9768270700
5        708   261_04  9820895896
6        710   261_05  7208615775
7        710   261_05  7208615775
8        710   261_05  7208615775
9        711   261_06  9920986486
10       800      234        Null
11       801      256        Null
12       803      289        Null