web-dev-qa-db-fra.com

pandas python remplaçant les chaînes dans le cadre de données par des nombres

Est-il possible d'utiliser la fonction de mappage ou quelque chose de mieux pour remplacer les valeurs dans une trame de données entière?

Je sais seulement comment effectuer le mappage sur des séries.

Je voudrais remplacer les chaînes dans les colonnes "tesst" et "set" par un nombre Par exemple, set = 1, test = 2

Voici un exemple de mon jeu de données: (Le jeu de données d'origine est très volumineux)

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

Le résultat final devrait être 

 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

reconnaissant pour le conseil,

25
jonas

Qu'en est-il 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  

Comme @Jeff l'a souligné dans les commentaires, dans les versions de pandas <0.11.1, insérez manuellement .convert_objects() à la fin pour convertir correctement tesst et définissez-le sur la colonne int64, au cas où cela aurait de l'importance pour les opérations suivantes.

38
Dan Allan

Je sais que c'est vieux, mais en ajoutant pour ceux qui cherchent comme j'étais. Créer une base de données dans pandas, df dans ce code

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

Cela vous donnera une carte du dictionnaire des adresses IP sans avoir à l'écrire.

16
Brandon

Vous pouvez utiliser la fonction applymap DataFrame pour cela:

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
4
bdiamante

Pour convertir des chaînes telles que 'volvo', 'bmw' en entiers, convertissez-la d'abord en un fichier de données, puis transmettez-la à pandas.get_dummies ()

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

Quand pas de fonctionnalités ne sont pas beaucoup:

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

Quand ce n'est pas possible manuellement:

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.
0
Akash Kandpal

Vous pouvez également le faire avec pandas rename_categories. Vous devez d’abord définir la colonne en tant que dtype="category" par exemple.

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]

et ensuite les renommer:

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]

Vous pouvez également transmettre un objet de type dict pour mapper le renommage, par exemple:

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