Pandas: làm thế nào để thay đổi tất cả các giá trị của một cột?


87

Tôi có một khung dữ liệu với một cột được gọi "Date"và muốn tất cả các giá trị từ cột này có cùng giá trị (chỉ năm). Thí dụ:

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

Điều tôi muốn là:

City     Date
Paris    2004
Lisbon   2004
Madrid   2004
Pekin    2004

Đây là mã của tôi:

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

Điều xảy ra là trong DataFrames của tôi, được gọi là ví dụ, fr['1961']các giá trị của Date_of_incorporationcó thể là bất kỳ thứ gì (chuỗi, số nguyên, v.v.), vì vậy có lẽ tốt nhất là xóa hoàn toàn cột này và sau đó gắn một cột khác chỉ có năm vào DataFrames?


1
Các chuỗi và số tùy thuộc vào việc chỉ có năm (như đối với Madrid trong ví dụ) hay có cả tháng và ngày (như đối với Pekin và Paris).
brodrigues

Câu trả lời:


128

Như @DSM đã chỉ ra, bạn có thể thực hiện việc này trực tiếp hơn bằng cách sử dụng các phương thức chuỗi vectorised :

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

Hoặc sử dụng giải nén (giả sử chỉ có một bộ chữ số có độ dài 4 ở đâu đó trong mỗi chuỗi):

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

Một cách thay thế linh hoạt hơn một chút, có thể là sử dụng apply(hoặc tương đương map) để làm điều này:

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

Hàm lambda, đang lấy đầu vào từ Datevà chuyển đổi nó thành một năm.
Bạn có thể (và có lẽ nên) viết điều này dài dòng hơn như:

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)

Có lẽ 'Năm' là một cái tên hay hơn cho cột này ...


1
Cảm ơn vì câu trả lời, nhưng nó phức tạp hơn thế: đôi khi các giá trị là một cái gì đó hoàn toàn khác (như ký tự). Tôi nghĩ sẽ đơn giản hơn nếu bỏ hoàn toàn cột này và sau đó thêm một cột mới với năm hoặc thay thế hoàn toàn các giá trị theo năm.
brodrigues

1
@cbrunos Vui lòng cung cấp một ví dụ mà cách này không hoạt động được không? (Nhưng bạn có thể điều chỉnh convert_to_yearđể đối phó với nó) ... Tôi đồng ý rằng một cái tên thích hợp hơn sẽ là df['Year'].
Andy Hayden

1
@cbrunos này nên làm việc tốt cho bạn: for year in fr: df=fr[year]; df['Year_of_incorporation']=df['Date_of_incorporation'].map(convert_to_year).
Andy Hayden

Những ngày này tôi thường làm những việc như df["Date"].str[-4:].astype(int).
DSM

1
@dmvianna hoặc có lẽs.str.extract('(?P<year>\d{4})')
Andy Hayden

29

Bạn có thể thực hiện chuyển đổi cột bằng cách sử dụng apply

Xác định một hàm sạch để loại bỏ đô la và dấu phẩy và chuyển đổi dữ liệu của bạn thành float.

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

Tiếp theo, gọi nó trên cột của bạn như thế này.

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

3

Hoặc nếu ai đó muốn sử dụng lambdahàm trong applyhàm:

data['Revenue']=data['Revenue'].apply(lambda x:float(x.replace("$","").replace(",", "").replace(" ", "")))
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.