Pandy: jak zmienić wszystkie wartości w kolumnie?


87

Mam ramkę danych z kolumną o nazwie "Date"i chcę, aby wszystkie wartości z tej kolumny miały tę samą wartość (tylko rok). Przykład:

City     Date
Paris    01/04/2004
Lisbon   01/09/2004
Madrid   2004
Pekin    31/2004

Chcę:

City     Date
Paris    2004
Lisbon   2004
Madrid   2004
Pekin    2004

Oto mój kod:

fr61_70xls = pd.ExcelFile('AMADEUS FRANCE 1961-1970.xlsx')

#Here we import the individual sheets and clean the sheets    
years=(['1961','1962','1963','1964','1965','1966','1967','1968','1969','1970'])

fr={}

header=(['City','Country','NACE','Cons','Last_year','Op_Rev_EUR_Last_avail_yr','BvD_Indep_Indic','GUO_Name','Legal_status','Date_of_incorporation','Legal_status_date'])

for year in years:
    # save every sheet in variable fr['1961'], fr['1962'] and so on
    fr[year]=fr61_70xls.parse(year,header=0,parse_cols=10)
    fr[year].columns=header
    # drop the entire Legal status date column
    fr[year]=fr[year].drop(['Legal_status_date','Date_of_incorporation'],axis=1)
    # drop every row where GUO Name is empty
    fr[year]=fr[year].dropna(axis=0,how='all',subset=[['GUO_Name']])
    fr[year]=fr[year].set_index(['GUO_Name','Date_of_incorporation'])

Zdarza się, że w moich DataFrames, nazywanych np fr['1961']. Wartościami, Date_of_incorporationmogą być cokolwiek (ciągi znaków, liczby całkowite itp.), Więc może najlepiej byłoby całkowicie wymazać tę kolumnę, a następnie dołączyć do DataFrames kolejną kolumnę z samym rokiem?


1
Ciągi i liczby w zależności od tego, czy jest tylko rok (jak na przykładzie Madrytu), czy też miesiąc i dzień (jak w Pekinie i Paryżu).
brodrigues

Odpowiedzi:


128

Jak wskazuje @DSM, możesz to zrobić bardziej bezpośrednio, używając wektoryzowanych metod ciągów :

df['Date'].str[-4:].astype(int)

Lub używając ekstraktu (zakładając, że w każdym łańcuchu jest tylko jeden zestaw cyfr o długości 4):

df['Date'].str.extract('(?P<year>\d{4})').astype(int)

Alternatywnym, nieco bardziej elastycznym sposobem może być użycie apply(lub równoważne map), aby to zrobić:

df['Date'] = df['Date'].apply(lambda x: int(str(x)[-4:]))
             #  converts the last 4 characters of the string to an integer

Funkcja lambda pobiera dane wejściowe z funkcji Datei konwertuje je na rok.
Możesz (i być może powinieneś) napisać to bardziej dosłownie jako:

def convert_to_year(date_in_some_format);
    date_as_string = str(date_in_some_format)
    year_as_string = date_in_some_format[-4:] # last four characters
    return int(year_as_string)

df['Date'] = df['Date'].apply(convert_to_year)

Być może „rok” to lepsza nazwa dla tej kolumny ...


1
Dzięki za odpowiedź, ale jest to bardziej skomplikowane: czasami wartości są czymś zupełnie innym (jak znaki). Myślę, że prościej byłoby całkowicie porzucić tę kolumnę, a następnie dodać nową z rokiem lub całkowicie zastąpić wartości rokiem.
brodrigues

1
@cbrunos Czy możesz podać przykład, w którym to nie działa? (Ale możesz dostosować, convert_to_yearaby sobie z tym poradzić) ... Zgadzam się, że bardziej odpowiednia byłaby nazwa df['Year'].
Andy Hayden

1
@cbrunos ten powinien działać dobrze dla Ciebie: for year in fr: df=fr[year]; df['Year_of_incorporation']=df['Date_of_incorporation'].map(convert_to_year).
Andy Hayden

Obecnie często robię takie rzeczy df["Date"].str[-4:].astype(int).
DSM

1
@dmvianna a możes.str.extract('(?P<year>\d{4})')
Andy Hayden

29

Możesz wykonać transformację kolumny za pomocą apply

Zdefiniuj czystą funkcję, aby usunąć dolara i przecinki i przekonwertować dane na zmiennoprzecinkowe.

def clean(x):
    x = x.replace("$", "").replace(",", "").replace(" ", "")
    return float(x)

Następnie nazwij to w swojej kolumnie w ten sposób.

data['Revenue'] = data['Revenue'].apply(clean)

3

Lub jeśli chcesz użyć lambdafunkcji w applyfunkcji:

data['Revenue']=data['Revenue'].apply(lambda x:float(x.replace("$","").replace(",", "").replace(" ", "")))
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.