2017-10-02 3 views
1

En donnant un exemple de trame de données avec les 2ème et 3ème colonnes de texte libre, par ex.Remplacement des nouvelles lignes par des espaces pour les colonnes str via pandas dataframe

>>> import pandas as pd 
>>> lol = [[1,2,'abc','foo\nbar'], [3,1, 'def\nhaha', 'love it\n']] 
>>> pd.DataFrame(lol) 
    0 1   2   3 
0 1 2  abc foo\nbar 
1 3 1 def\nhaha love it\n 

Le but est de remplacer le \n- (espace) et la bande de la chaîne dans la colonne 2 et 3 pour obtenir:

>>> pd.DataFrame(lol) 
    0 1   2  3 
0 1 2  abc foo bar 
1 3 1 def haha love it 

Comment remplacer les sauts de lignes avec des espaces pour des colonnes spécifiques par le biais de pandas trame de données?

J'ai essayé:

>>> import pandas as pd 
>>> lol = [[1,2,'abc','foo\nbar'], [3,1, 'def\nhaha', 'love it\n']] 

>>> replace_and_strip = lambda x: x.replace('\n', ' ').strip() 

>>> lol2 = [[replace_and_strip(col) if type(col) == str else col for col in list(row)] for idx, row in pd.DataFrame(lol).iterrows()] 

>>> pd.DataFrame(lol2) 
    0 1   2  3 
0 1 2  abc foo bar 
1 3 1 def haha love it 

Mais il doit y avoir une meilleure/façon plus simple.

Répondre

1

utilisation replace - première première et la dernière bande, puis remplacer \n:

df = df.replace({r'\s+$': '', r'^\s+': ''}, regex=True).replace(r'\n', ' ', regex=True) 
print (df) 
    0 1   2  3 
0 1 2  abc foo bar 
1 3 1 def haha love it 
1

Vous pouvez utiliser les deux regex remplacer l'approche suivante:

>>> df.replace({ r'\A\s+|\s+\Z': '', '\n' : ' '}, regex=True, inplace=True) 
>>> df 
    0 1   2  3 
0 1 2  abc foo bar 
1 3 1 def haha love it 
>>> 

Détails

  • '\A\s+|\s+\Z' ->'' va agir comme strip() supprimant tous les espaces avant et:
    • \A\s+ - correspond à 1 ou plus whitespa symboles CE au début de la chaîne
    • | - ou
    • \s+\Z - correspond à 1 ou plusieurs symboles blancs à la fin de la chaîne
  • '\n' ->' ' remplacera toute nouvelle ligne avec un espace.
1

Vous pouvez select_dtypes pour sélectionner les colonnes de type object et utiliser applymap sur ces colonnes.

Parce qu'il n'y a aucun argument inplace pour ces fonctions, ce serait une solution de contournement pour faire modifier la trame de données:

strs = lol.select_dtypes(include=['object']).applymap(lambda x: x.replace('\n', ' ').strip()) 
lol[strs.columns] = strs 
lol 
# 0 1   2  3 
#0 1 2  abc foo bar 
#1 3 1 def haha love it 
1

Ajout aux autres réponses belles, ceci est une version vectorisée de votre idée initiale:

columns = [2,3] 
df.iloc[:, columns] = [df.iloc[:,col].str.strip().str.replace('\n',' ') 
         for col in columns] 

Détails:

In [49]: df.iloc[:, columns] = [df.iloc[:,col].str.strip().str.replace('\n',' ') 
           for col in columns] 

In [50]: df 
Out[50]: 
    0 1  2   3 
0 1 2  abc def haha 
1 3 1 foo bar love it