Thêm cột trong khung dữ liệu từ danh sách


94

Tôi có một khung dữ liệu với một số cột như sau:

A   B   C  
0   
4
5
6
7
7
6
5

Các phạm vi có thể của giá trị trong A là chỉ 0-7 .

Ngoài ra, tôi có một danh sách gồm 8 yếu tố như sau:

List=[2,5,6,8,12,16,26,32]  //There are only 8 elements in this list

Nếu phần tử trong cột A là n , tôi cần chèn phần tử thứ n từ Danh sách vào một cột mới, nói 'D'.

Làm cách nào tôi có thể thực hiện việc này trong một lần mà không lặp lại toàn bộ khung dữ liệu?

Khung dữ liệu kết quả sẽ giống như sau:

A   B   C   D
0           2
4           12
5           16
6           26
7           32
7           32
6           26
5           16

Lưu ý: Khung dữ liệu rất lớn và lặp lại là tùy chọn cuối cùng. Nhưng tôi cũng có thể sắp xếp các phần tử trong 'Danh sách' trong bất kỳ cấu trúc dữ liệu nào khác như dict nếu cần.


1
Tôi nghĩ bạn cần một ví dụ đồ chơi (nhỏ hơn), với kết quả mong muốn. Nghe có vẻ hơi mơ hồ atm.
Andy Hayden,

11
Đừng bao giờ gọi một biến là "Danh sách". Bằng bất kỳ ngôn ngữ nào.
lucid_dreamer

Câu trả lời:


50

IIUC, nếu bạn biến (không may được đặt tên) Listthành một ndarray, bạn có thể chỉ mục vào nó một cách tự nhiên.

>>> import numpy as np
>>> m = np.arange(16)*10
>>> m[df.A]
array([  0,  40,  50,  60, 150, 150, 140, 130])
>>> df["D"] = m[df.A]
>>> df
    A   B   C    D
0   0 NaN NaN    0
1   4 NaN NaN   40
2   5 NaN NaN   50
3   6 NaN NaN   60
4  15 NaN NaN  150
5  15 NaN NaN  150
6  14 NaN NaN  140
7  13 NaN NaN  130

Ở đây tôi đã tạo một cái mới m, nhưng nếu bạn sử dụng m = np.asarray(List), điều tương tự sẽ hoạt động: các giá trị trong df.Asẽ chọn ra các phần tử thích hợp của m.


Lưu ý rằng nếu bạn đang sử dụng phiên bản cũ của numpy, bạn có thể phải sử dụng m[df.A.values]thay thế - trước đây, numpykhông chơi tốt với những người khác và một số cấu trúc lại pandasgây ra một số đau đầu. Mọi thứ đã được cải thiện bây giờ.


Xin chào @DSM. Tôi có được những gì bạn đang nói nhưng tôi nhận được lỗi này: Traceback (most recent call last): File "./b.py", line 24, in <module> d["D"] = m[d.A] IndexError: unsupported iterator index
bờm

1
@mane: urf, đó là một numpylỗi cũ . Có d["D"] = m[d.A.values]làm việc cho bạn?
DSM

277

Chỉ cần chỉ định danh sách trực tiếp:

df['new_col'] = mylist

Thay thế
Chuyển đổi danh sách thành một chuỗi hoặc mảng và sau đó gán:

se = pd.Series(mylist)
df['new_col'] = se.values

hoặc là

df['new_col'] = np.array(mylist)

3
pykernel_launcher.py:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy """Entry point for launching an IPython kernel.
Ilya Rusin

@sparrow sẽ sử dụng pd.Seriesloại dtype có hiệu lực không? Ý tôi là nó sẽ để float như float và string là string? Hay các phần tử trong danh sách sẽ mặc định thành chuỗi?
3kstc

2
@IlyaRusin, đó là một dương tính giả có thể được bỏ qua trong trường hợp này. Để biết thêm thông tin: stackoverflow.com/questions/20625582/…
sparrow,

1
Điều này có thể được đơn giản hóa thành: df ['new_col'] = pd.Series (mylist) .values
smartse

15

Giải pháp cải tiến từ @sparrow.

Hãy df , hãy tập dữ liệu của bạn, và mylist danh sách với các giá trị bạn muốn thêm vào các dataframe.

Giả sử bạn muốn gọi cột mới của mình đơn giản là new_column

Đầu tiên, hãy tạo danh sách thành một Chuỗi:

column_values = pd.Series(mylist)

Sau đó sử dụng chức năng chèn để thêm cột. Chức năng này có ưu điểm là cho phép bạn chọn vị trí bạn muốn đặt cột. Trong ví dụ sau, chúng tôi sẽ đặt cột mới ở vị trí đầu tiên từ trái sang (bằng cách đặt loc = 0)

df.insert(loc=0, column='new_column', value=column_values)

Điều này sẽ không hoạt động nếu bạn đã thay đổi các chỉ mục của df thành một cái gì đó khác rồi 1,2,3 ... trong trường hợp đó bạn phải thêm vào giữa các dòng: column_values.index = df.index
Guys

8

Đầu tiên, hãy tạo khung dữ liệu mà bạn đã có, tôi sẽ bỏ qua cột B và C vì chúng không liên quan.

df = pd.DataFrame({'A': [0, 4, 5, 6, 7, 7, 6,5]})

Và ánh xạ mà bạn mong muốn:

mapping = dict(enumerate([2,5,6,8,12,16,26,32]))

df['D'] = df['A'].map(mapping)

Làm xong!

print df

Đầu ra:

   A   D
0  0   2
1  4  12
2  5  16
3  6  26
4  7  32
5  7  32
6  6  26
7  5  16

1
Tôi nghĩ OP đã biết cách làm điều này. Bằng cách đọc của tôi, vấn đề được xây dựng Dtừ các phần tử của AList("Nếu phần tử trong cột A là n, tôi cần chèn phần tử thứ n từ Danh sách vào một cột mới, giả sử 'D'.")
DSM

SO đã biến thành một loại trạng thái F (* & vú em. Cảm ơn @DSM đã nhận xét nhưng tôi không thể sửa bài đăng cho đến khi nó được đồng nghiệp đánh giá. Và sau đó nó bị từ chối vì quá nhanh. Và sau đó tôi đã .. có thể nhìn xem xét chỉnh sửa của riêng tôi và sau đó nó đã quá muộn vì một (IMHO) câu trả lời tồi tệ hơn được "chấp nhận" sO thực sự là có một số meta-vú em là người kém hơn hữu ích !!!!
Phil Cooper

Chà, tôi không thể nói thay cho các vú em, nhưng bạn sẽ thấy rằng cách tiếp cận của bạn chậm hơn về thứ tự cấp độ đối với các mảng dài. Tất nhiên, ở các khía cạnh khác, việc lựa chọn giữa np.array(List)[df.A]df["A"].map(dict(enumerate(List)))chủ yếu là vấn đề sở thích.
DSM

Xin chào Phil, tôi chỉ thấy giải pháp của bạn và nhận xét của DSM và sau đó không bao giờ xem lại vì giải pháp của DSM phù hợp với tôi. Nhưng bây giờ nhìn vào giải pháp của bạn, nó cũng hoạt động. Tôi đã chạy giải pháp của DSM trên tập dữ liệu khoảng 200 nghìn mục nhập của mình và nó chạy trong vài giây với tất cả các phép tính khác mà tôi có. Tôi hoàn toàn mới đối với gấu trúc trăn và cá nhân tôi không tìm kiếm bất cứ thứ gì trang nhã hay tuyệt vời; bất cứ điều gì làm việc tốt. Nhưng thành thật mà nói, cảm ơn vì giải pháp.
bờm

2

Câu hỏi cũ; nhưng tôi luôn cố gắng sử dụng mã nhanh nhất!

Tôi đã có một danh sách khổng lồ với 69 triệu uint64. np.array () là nhanh nhất đối với tôi.

df['hashes'] = hashes
Time spent: 17.034842014312744

df['hashes'] = pd.Series(hashes).values
Time spent: 17.141014337539673

df['key'] = np.array(hashes)
Time spent: 10.724546194076538
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.