Pandas: como alterar todos os valores de uma coluna?

87

Eu tenho um quadro de dados com uma coluna chamada "Date"e quero que todos os valores desta coluna tenham o mesmo valor (apenas o ano). Exemplo:

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

O que eu quero é:

City     Date
Paris    2004
Lisbon   2004
Madrid   2004
Pekin    2004

Aqui está o meu código:

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

Acontece que em meus DataFrames, chamados por exemplo, fr['1961']os valores de Date_of_incorporationpodem ser qualquer coisa (strings, inteiro e assim por diante), então talvez seja melhor apagar completamente esta coluna e então anexar outra coluna com apenas o ano aos DataFrames?

Brodrigues
fonte
1
Strings e números dependendo se há apenas o ano (como para Madrid no exemplo), ou se há também o mês e o dia (como para Pekin e Paris).
brodrigues

Respostas:

128

Como @DSM aponta, você pode fazer isso mais diretamente usando os métodos de string vetorizados :

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

Ou usando extrair (assumindo que haja apenas um conjunto de dígitos de comprimento 4 em algum lugar em cada string):

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

Uma forma alternativa um pouco mais flexível pode ser usar apply(ou de forma equivalente map) para fazer isso:

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

A função lambda está pegando a entrada de Datee convertendo-a em um ano.
Você poderia (e talvez devesse) escrever mais detalhadamente como:

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)

Talvez 'Ano' seja um nome melhor para esta coluna ...

Andy Hayden
fonte
1
Obrigado pela resposta, mas é mais complicado do que isso: às vezes os valores são algo totalmente diferente (como personagens). Acho que seria mais simples eliminar completamente esta coluna e, em seguida, adicionar uma nova com o ano, ou substituir completamente os valores pelo ano.
brodrigues
1
@cbrunos Por favor, você poderia fornecer um exemplo em que isso não funciona? (Mas você pode ajustar o convert_to_yearpara lidar com isso) ... Concordo que um nome mais apropriado seria df['Year'].
Andy Hayden
1
@cbrunos Isso deve funcionar bem para você: for year in fr: df=fr[year]; df['Year_of_incorporation']=df['Date_of_incorporation'].map(convert_to_year).
Andy Hayden
Hoje em dia, costumo fazer coisas assim df["Date"].str[-4:].astype(int).
DSM
1
@dmvianna ou talvezs.str.extract('(?P<year>\d{4})')
Andy Hayden
29

Você pode fazer uma transformação de coluna usando apply

Defina uma função limpa para remover o dólar e as vírgulas e converter seus dados em float.

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

Em seguida, chame-o em sua coluna assim.

data['Revenue'] = data['Revenue'].apply(clean)
nim94
fonte
3

Ou se alguém quiser usar a lambdafunção na applyfunção:

data['Revenue']=data['Revenue'].apply(lambda x:float(x.replace("$","").replace(",", "").replace(" ", "")))
Tanmay
fonte