Konwersja kolumny w pandas dataframe z int na string

109

Mam ramkę danych w pandach z mieszanymi kolumnami danych int i str. Chcę najpierw połączyć kolumny w ramce danych. Aby to zrobić, muszę przekonwertować intkolumnę na str. Próbowałem zrobić co następuje:

mtrx['X.3'] = mtrx.to_string(columns = ['X.3'])

lub

mtrx['X.3'] = mtrx['X.3'].astype(str)

ale w obu przypadkach to nie działa i otrzymuję komunikat o błędzie „nie można połączyć obiektów„ str ”i„ int ””. Łączenie dwóch strkolumn działa doskonale.

Malfet
źródło

Odpowiedzi:

142
In [16]: df = DataFrame(np.arange(10).reshape(5,2),columns=list('AB'))

In [17]: df
Out[17]: 
   A  B
0  0  1
1  2  3
2  4  5
3  6  7
4  8  9

In [18]: df.dtypes
Out[18]: 
A    int64
B    int64
dtype: object

Konwertuj serię

In [19]: df['A'].apply(str)
Out[19]: 
0    0
1    2
2    4
3    6
4    8
Name: A, dtype: object

In [20]: df['A'].apply(str)[0]
Out[20]: '0'

Nie zapomnij przypisać wyniku z powrotem:

df['A'] = df['A'].apply(str)

Konwertuj całą ramkę

In [21]: df.applymap(str)
Out[21]: 
   A  B
0  0  1
1  2  3
2  4  5
3  6  7
4  8  9

In [22]: df.applymap(str).iloc[0,0]
Out[22]: '0'

df = df.applymap(str)
Jeff
źródło
3
Naprawdę nie rozumiem dlaczego, ale mtrx ['X.3']. Apply (str) też nie działa dla mnie :( dtype nadal pokazuje int64. Dataframe dla 23177 wiersza i kolumny X.3 ma tylko liczby. W [21]: mtrx ['X.3']. Dtype Out [21]: dtype ('int64')
Malfet
0.7.0, dostarczany z
Pythonem
aktualna wersja to 0.12, powinieneś dokonać aktualizacji.
Jeff,
df ['A']. apply (str) nie działa. ale df.column_name = df.column_name.astype (str) działa. Nie mam pojęcia dlaczego.
Dmitry Konovalov
1
@DmitryKonovalov w ciągach znaków Pythona są niezmienne, więc za każdym razem, gdy manipulujesz danymi, musisz umieścić wynik z powrotem w zmiennej.
Sriram Arvind Lakshmanakumar
92

Zmień typ danych kolumny DataFrame:

Do int:

df.column_name = df.column_name.astype(np.int64)

Do str:

df.column_name = df.column_name.astype(str)

tanaque
źródło
7
Jest to atrakcyjne, ale apply(str)w moim teście jest około 4x wolniejsze niż z @Jeff pd.Series(np.arange(1000000)).
John Zwinck
2
To działa dla mnie. df['A'] = df['A'].apply(str)też działa. Odpowiedź udzielona przez @Jeff nie działa dla mnie.
tommy.carstensen
1
Odnośnie komentarza @JohnZwinck, użycie Pythona3 wydaje się być bardziej podobne do 2x szybciej w użyciu apply()zamiast astype(): timeit.Timer ('c.apply (str)', setup = 'import pandas as pd; c = pd.Series (range ( 1000)) '). Timeit (1000) >>> 0.41499893204309046 >>> timeit.Timer (' c.astype (str) ', setup =' import pandy as pd; c = pd.Series (range (1000)) ' ) .timeit (1000) 0.8004439630312845
hamx0r
15

Ostrzeżenie : oba podane rozwiązania ( astype () i apply () ) nie zachowują wartości NULL ani w formie nan, ani w postaci None.

import pandas as pd
import numpy as np

df = pd.DataFrame([None,'string',np.nan,42], index=[0,1,2,3], columns=['A'])

df1 = df['A'].astype(str)
df2 =  df['A'].apply(str)

print df.isnull()
print df1.isnull()
print df2.isnull()

Uważam, że jest to naprawione przez implementację to_string ()

Keith
źródło
1
to_string pozwala wybrać obsługę Nan, np. aby zwrócić pusty ciąg zamiast „Nan”
seanv507
1
(Nie
zgadzałem się
8

Użyj poniższego kodu:

df.column_name = df.column_name.astype('str')
Faraz Ramtin
źródło
0

Tylko dla dodatkowego odniesienia.

Wszystkie powyższe odpowiedzi będą działać w przypadku ramki danych. Ale jeśli używasz lambda podczas tworzenia / modyfikowania kolumny, to nie zadziała, ponieważ tam jest traktowany jako atrybut int zamiast serii pand. Musisz użyć str (target_attribute), aby uczynić go ciągiem. Proszę zapoznać się z poniższym przykładem.

def add_zero_in_prefix(df):
    if(df['Hour']<10):
        return '0' + str(df['Hour'])

data['str_hr'] = data.apply(add_zero_in_prefix, axis=1)
sujithramanathan
źródło