Панды: как изменить все значения столбца?


87

У меня есть фрейм данных с названным столбцом, "Date"и я хочу, чтобы все значения из этого столбца имели одинаковое значение (только год). Пример:

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

Я хочу:

City     Date
Paris    2004
Lisbon   2004
Madrid   2004
Pekin    2004

Вот мой код:

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'])

Бывает, что в моих DataFrames, например, вызываемые fr['1961']значения Date_of_incorporationмогут быть любыми (строки, целые числа и т. Д.), Поэтому, может быть, было бы лучше полностью стереть этот столбец, а затем прикрепить другой столбец только с годом к DataFrames?


1
Строки и числа в зависимости от того, есть ли только год (как для Мадрида в примере) или есть также месяц и день (как для Пекина и Парижа).
brodrigues

Ответы:


128

Как указывает @DSM, вы можете сделать это напрямую, используя методы векторизованных строк :

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

Или с помощью extract (при условии, что где-то в каждой строке есть только один набор цифр длиной 4):

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

Альтернативным немного более гибким способом может быть использование apply(или что- mapто подобное) для этого:

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

Лямбда-функция принимает входные данные из Dateи преобразует их в год.
Вы могли бы (и, возможно, должны) написать это более подробно как:

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)

Возможно, «Год» - лучшее название для этой колонки ...


1
Спасибо за ответ, но дело обстоит сложнее: иногда значения представляют собой нечто совсем другое (например, символы). Я думаю, что было бы проще полностью отбросить этот столбец, а затем добавить новый с годом или полностью заменить значения на год.
brodrigues

1
@cbrunos Не могли бы вы привести пример, когда это не работает? (Но вы можете настроить, convert_to_yearчтобы справиться с этим) ... Я согласен, что было бы более подходящее имя df['Year'].
Энди Хайден

1
@cbrunos Это должно работать нормально для вас: for year in fr: df=fr[year]; df['Year_of_incorporation']=df['Date_of_incorporation'].map(convert_to_year).
Энди Хайден,

В наши дни я часто делаю такие вещи df["Date"].str[-4:].astype(int).
DSM

1
@dmvianna или возможноs.str.extract('(?P<year>\d{4})')
Энди Хайден

29

Вы можете выполнить преобразование столбца, используя apply

Определите чистую функцию для удаления доллара и запятых и преобразования ваших данных в плавающие.

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

Затем назовите его в своем столбце вот так.

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

3

Или, если вы хотите использовать lambdaфункцию в applyфункции:

data['Revenue']=data['Revenue'].apply(lambda x:float(x.replace("$","").replace(",", "").replace(" ", "")))
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.