【问题标题】:python pandas replacing strings in dataframe with numberspython pandas用数字替换数据框中的字符串
【发布时间】:2013-06-11 11:33:38
【问题描述】:

有没有办法使用映射函数或更好的方法来替换整个数据框中的值?

我只知道如何对系列进行映射。

我想用数字替换 'test' 和 'set' 列中的字符串 例如设置=1,测试=2

这是我的数据集的示例:(原始数据集非常大)

ds_r
  respondent  brand engine  country  aware  aware_2  aware_3  age tesst   set
0          a  volvo      p      swe      1        0        1   23   set   set
1          b  volvo   None      swe      0        0        1   45   set   set
2          c    bmw      p       us      0        0        1   56  test  test
3          d    bmw      p       us      0        1        1   43  test  test
4          e    bmw      d  germany      1        0        1   34   set   set
5          f   audi      d  germany      1        0        1   59   set   set
6          g  volvo      d      swe      1        0        0   65  test   set
7          h   audi      d      swe      1        0        0   78  test   set
8          i  volvo      d       us      1        1        1   32   set   set

最终结果应该是

 ds_r
  respondent  brand engine  country  aware  aware_2  aware_3  age  tesst  set
0          a  volvo      p      swe      1        0        1   23      1    1
1          b  volvo   None      swe      0        0        1   45      1    1
2          c    bmw      p       us      0        0        1   56      2    2
3          d    bmw      p       us      0        1        1   43      2    2
4          e    bmw      d  germany      1        0        1   34      1    1
5          f   audi      d  germany      1        0        1   59      1    1
6          g  volvo      d      swe      1        0        0   65      2    1
7          h   audi      d      swe      1        0        0   78      2    1
8          i  volvo      d       us      1        1        1   32      1    1

【问题讨论】:

    标签: python replace dataframe pandas


    【解决方案1】:

    您可以从column 值本身构建dictionary 并填充如下

    x=df['Item_Type'].value_counts()
    item_type_mapping={}
    item_list=x.index
    for i in range(0,len(item_list)):
        item_type_mapping[item_list[i]]=i
    
    df['Item_Type']=df['Item_Type'].map(lambda x:item_type_mapping[x]) 
    

    【讨论】:

      【解决方案2】:

      替换数据框中任何值的最简单方法:

      df=df.replace(to_replace="set",value="1")
      df=df.replace(to_replace="test",value="2")
      

      希望这会有所帮助。

      【讨论】:

        【解决方案3】:

        要将“volvo”、“bmw”等字符串转换为整数,首先将其转换为数据帧,然后将其传递给 pandas.get_dummies()

          df  = DataFrame.from_csv("myFile.csv")
          df_transform = pd.get_dummies( df )
          print( df_transform )
        

        更好的选择:将字典传递给 pandas 系列 (df.myCol) 的 map() (例如通过指定列品牌)

        df.brand = df.brand.map( {'volvo':0 , 'bmw':1, 'audi':2} )
        

        【讨论】:

          【解决方案4】:

          来自@Ishnark 的df.replace(to_replace=['set', 'test'], value=[1, 2]) 对接受的答案发表评论。

          【讨论】:

            【解决方案5】:

            当特征数量不多时:

            mymap = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5}
            df.applymap(lambda s: mymap.get(s) if s in mymap else s)
            

            当无法手动操作时:

            temp_df2 = pd.DataFrame({'data': data.data.unique(), 'data_new':range(len(data.data.unique()))})# create a temporary dataframe 
            data = data.merge(temp_df2, on='data', how='left')# Now merge it by assigning different values to different strings.
            

            【讨论】:

              【解决方案6】:

              您也可以使用 pandas rename_categories 来执行此操作。您首先需要将列定义为 dtype="category" 例如

              In [66]: s = pd.Series(["a","b","c","a"], dtype="category")
              
              In [67]: s
              Out[67]: 
              0    a
              1    b
              2    c
              3    a
              dtype: category
              Categories (3, object): [a, b, c]
              

              然后重命名它们:

              In [70]: s.cat.rename_categories([1,2,3])
              Out[70]: 
              0    1
              1    2
              2    3
              3    1
              dtype: category
              Categories (3, int64): [1, 2, 3]
              

              你也可以传递一个类似dict的对象来映射重命名,例如:

              In [72]: s.cat.rename_categories({1: 'x', 2: 'y', 3: 'z'})
              

              【讨论】:

              【解决方案7】:

              我知道这是旧的,但为那些像我一样搜索的人添加。在 pandas 中创建一个数据框,在这段代码中使用 df

              ip_addresses = df.source_ip.unique()
              ip_dict = dict(zip(ip_addresses, range(len(ip_addresses))))
              

              这将为您提供 IP 地址的字典映射,而无需将其写出来。

              【讨论】:

                【解决方案8】:

                DataFrame.replace 呢?

                In [9]: mapping = {'set': 1, 'test': 2}
                
                In [10]: df.replace({'set': mapping, 'tesst': mapping})
                Out[10]: 
                   Unnamed: 0 respondent  brand engine  country  aware  aware_2  aware_3  age  \
                0           0          a  volvo      p      swe      1        0        1   23   
                1           1          b  volvo   None      swe      0        0        1   45   
                2           2          c    bmw      p       us      0        0        1   56   
                3           3          d    bmw      p       us      0        1        1   43   
                4           4          e    bmw      d  germany      1        0        1   34   
                5           5          f   audi      d  germany      1        0        1   59   
                6           6          g  volvo      d      swe      1        0        0   65   
                7           7          h   audi      d      swe      1        0        0   78   
                8           8          i  volvo      d       us      1        1        1   32   
                
                  tesst set  
                0     2   1  
                1     1   2  
                2     2   1  
                3     1   2  
                4     2   1  
                5     1   2  
                6     2   1  
                7     1   2  
                8     2   1  
                

                正如@Jeff 在 cmets 中指出的那样,在 pandas 版本 .convert_objects() 添加到末尾以正确转换 testst 并设置为 int64 列,以防在后续操作中很重要。

                【讨论】:

                • 请注意,您可能希望在替换后执行 df.convert_objects() 以强制转换为正确的 dtypes
                • @Dan Allan 这将是 0.11.1 中的默认设置,仅供参考(转换为对象)
                • 这是超级旧的,但你现在也可以这样做:df.replace(to_replace=['set', 'test'], value=[1, 2])
                • 我认为我们不应该要求硬编码值的名称,它应该在运行时动态提取并分配编号。
                【解决方案9】:

                您可以使用applymap DataFrame 函数来执行此操作:

                In [26]: df = DataFrame({"A": [1,2,3,4,5], "B": ['a','b','c','d','e'],
                                         "C": ['b','a','c','c','d'], "D": ['a','c',7,9,2]})
                In [27]: df
                Out[27]:
                   A  B  C  D
                0  1  a  b  a
                1  2  b  a  c
                2  3  c  c  7
                3  4  d  c  9
                4  5  e  d  2
                
                In [28]: mymap = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5}
                
                In [29]: df.applymap(lambda s: mymap.get(s) if s in mymap else s)
                Out[29]:
                   A  B  C  D
                0  1  1  2  1
                1  2  2  1  3
                2  3  3  3  7
                3  4  4  3  9
                4  5  5  4  2
                

                【讨论】:

                • 我正在解决这样的问题,我只是按照您的答案中提到的确切步骤进行操作。我没有得到输出。 代码: wc = pd.read_csv('PATH', usecols = ['Workclass'])
                • df = pd.DataFrame(wc) 行尾 wcdict = {"?":0,"Federal-gov":1,"Local-gov":2 ,"从未工作过":3,"私人":4,"Self-emp-inc":5, "Self-emp-n-inc":6,"State-gov":7,"Without-pay" :8} 行尾 df.applymap(lambda s: wcdict.get(s) if s in wcdict else s) 行尾 print(df)
                • df.applymap(lambda s: mymap.get(s) if s in mymap else s) 不会对 df 进行内联更改,因此您的 print df 语句不会反映 applymap 的结果。你需要做一个像df2 = df.applymap(lambda s: mymap.get(s) if s in mymap else s) 这样的分配。 print df2 现在将反映更改。
                • 成功了!!谢谢 :) 我还有一个问题,我需要使用 pyspark 而不是使用普通的 python。这个逻辑的实现在 pyspark 中是否有所不同?当我创建一个数据框时,我给出了文件路径[如上面的 cmets 所示],但是,我想给出一个 RDD 作为数据框的输入。我不能那样做。你对此有什么想法吗?
                • 很高兴它成功了。我真的不确定......也许this 可能是一个开始?
                猜你喜欢
                • 2012-12-30
                • 1970-01-01
                • 1970-01-01
                • 2022-12-03
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2021-05-13
                相关资源
                最近更新 更多