【问题标题】:how to rename a column value in pandas dataframe on some condition如何在某些条件下重命名熊猫数据框中的列值
【发布时间】:2016-02-20 11:15:13
【问题描述】:

我有一个这样的熊猫数据框:

 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

我可以使用以下代码在261buyer_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

所以7208615775phone_no 应该是261_05,但它给出的是261_09

【问题讨论】:

    标签: python pandas dataframe cumsum


    【解决方案1】:

    原始问题

    首先找到唯一的电话号码并创建 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
    

    【讨论】:

    • Muller 太棒了,非常感谢.. 以我想要的方式工作.. :)
    【解决方案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
    

    编辑:

    如果您想要在buyer_id 列中过滤值261,您可以使用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
    

    【讨论】:

    • 我在phone_no 列中有空值如何处理。重命名261buyer_id 时,我只想处理电话号码
    • @jazrael 您的代码在输出之后返回给我。我正在编辑它
    • 在处理之前是否可以按列 phone_no 对值进行排序?
    • 非常感谢您的回答:)
    猜你喜欢
    • 1970-01-01
    • 2019-09-15
    • 2016-08-07
    • 2019-09-06
    • 2023-03-14
    • 1970-01-01
    • 2014-11-23
    • 2022-12-17
    • 1970-01-01
    相关资源
    最近更新 更多