gấu trúc giá trị duy nhất nhiều cột


134
df = pd.DataFrame({'Col1': ['Bob', 'Joe', 'Bill', 'Mary', 'Joe'],
                   'Col2': ['Joe', 'Steve', 'Bob', 'Bob', 'Steve'],
                   'Col3': np.random.random(5)})

Cách tốt nhất để trả về các giá trị duy nhất của 'Col1' và 'Col2' là gì?

Đầu ra mong muốn là

'Bob', 'Joe', 'Bill', 'Mary', 'Steve'

3
Xem thêm các kết hợp giá trị duy nhất trong các cột được chọn trong khung dữ liệu gấu trúc và tính cho một câu hỏi khác nhau nhưng có liên quan. Câu trả lời được chọn ở đó sử dụngdf1.groupby(['A','B']).size().reset_index().rename(columns={0:'count'})
Paul Rougieux

Câu trả lời:


198

pd.unique trả về các giá trị duy nhất từ ​​một mảng đầu vào hoặc cột hoặc chỉ mục DataFrame.

Đầu vào của hàm này cần phải là một chiều, do đó, nhiều cột sẽ cần được kết hợp. Cách đơn giản nhất là chọn các cột bạn muốn và sau đó xem các giá trị trong một mảng NumPy được làm phẳng. Toàn bộ hoạt động trông như thế này:

>>> pd.unique(df[['Col1', 'Col2']].values.ravel('K'))
array(['Bob', 'Joe', 'Bill', 'Mary', 'Steve'], dtype=object)

Lưu ý rằng đó ravel()là một phương thức mảng hơn trả về một khung nhìn (nếu có thể) của một mảng nhiều chiều. Đối số 'K'cho biết phương thức làm phẳng mảng theo thứ tự các phần tử được lưu trữ trong bộ nhớ (gấu trúc thường lưu trữ các mảng bên dưới theo thứ tự tiếp giáp Fortran ; các cột trước các hàng). Điều này có thể nhanh hơn đáng kể so với sử dụng thứ tự 'C' mặc định của phương thức.


Một cách khác là chọn các cột và chuyển chúng tới np.unique:

>>> np.unique(df[['Col1', 'Col2']].values)
array(['Bill', 'Bob', 'Joe', 'Mary', 'Steve'], dtype=object)

Không cần sử dụng ravel()ở đây vì phương thức xử lý các mảng nhiều chiều. Mặc dù vậy, điều này có khả năng chậm hơnpd.unique với việc nó sử dụng thuật toán dựa trên sắp xếp thay vì hashtable để xác định các giá trị duy nhất.

Sự khác biệt về tốc độ rất có ý nghĩa đối với DataFrames lớn hơn (đặc biệt là nếu chỉ có một số giá trị duy nhất):

>>> df1 = pd.concat([df]*100000, ignore_index=True) # DataFrame with 500000 rows
>>> %timeit np.unique(df1[['Col1', 'Col2']].values)
1 loop, best of 3: 1.12 s per loop

>>> %timeit pd.unique(df1[['Col1', 'Col2']].values.ravel('K'))
10 loops, best of 3: 38.9 ms per loop

>>> %timeit pd.unique(df1[['Col1', 'Col2']].values.ravel()) # ravel using C order
10 loops, best of 3: 49.9 ms per loop

2
Làm thế nào để bạn lấy lại một dataframe thay vì một mảng?
Lisle

1
@ Lối đi: cả hai phương thức đều trả về một mảng NumPy, vì vậy bạn sẽ phải xây dựng nó theo cách thủ công, ví dụ : pd.DataFrame(unique_values). Không có cách nào tốt để lấy lại DataFrame trực tiếp.
Alex Riley

@Lisle vì anh ta đã sử dụng pd.unique, nó trả về một numpy.ndarray làm đầu ra cuối cùng. Đây có phải là những gì bạn đang hỏi?
Ash Upadhyay

1
@ Lối đi, có thể cái này df = df.drop_d repeatates (tập hợp con = ['C1', 'C2', 'C3'])?
khoai tây cù lét

14

Tôi đã thiết lập một DataFramevài chuỗi đơn giản trong các cột của nó:

>>> df
   a  b
0  a  g
1  b  h
2  d  a
3  e  e

Bạn có thể nối các cột bạn quan tâm và gọi uniquehàm:

>>> pandas.concat([df['a'], df['b']]).unique()
array(['a', 'b', 'd', 'e', 'g', 'h'], dtype=object)

7
In [5]: set(df.Col1).union(set(df.Col2))
Out[5]: {'Bill', 'Bob', 'Joe', 'Mary', 'Steve'}

Hoặc là:

set(df.Col1) | set(df.Col2)


1

Không pandasgiải pháp: sử dụng set ().

import pandas as pd
import numpy as np

df = pd.DataFrame({'Col1' : ['Bob', 'Joe', 'Bill', 'Mary', 'Joe'],
              'Col2' : ['Joe', 'Steve', 'Bob', 'Bob', 'Steve'],
               'Col3' : np.random.random(5)})

print df

print set(df.Col1.append(df.Col2).values)

Đầu ra:

   Col1   Col2      Col3
0   Bob    Joe  0.201079
1   Joe  Steve  0.703279
2  Bill    Bob  0.722724
3  Mary    Bob  0.093912
4   Joe  Steve  0.766027
set(['Steve', 'Bob', 'Bill', 'Joe', 'Mary'])

1

Đối với những người trong chúng ta yêu thích tất cả những thứ gấu trúc, hãy áp dụng, và tất nhiên chức năng lambda:

df['Col3'] = df[['Col1', 'Col2']].apply(lambda x: ''.join(x), axis=1)

1

đây là một cách khác


import numpy as np
set(np.concatenate(df.values))

0
list(set(df[['Col1', 'Col2']].as_matrix().reshape((1,-1)).tolist()[0]))

Đầu ra sẽ là ['Mary', 'Joe', 'Steve', 'Bob', 'Bill']

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.