panda menghargai beberapa kolom

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

Apa cara terbaik untuk mengembalikan nilai unik 'Col1' dan 'Col2'?

Output yang diinginkan adalah

'Bob', 'Joe', 'Bill', 'Mary', 'Steve'
pengguna2333196
sumber
3
Lihat juga kombinasi unik dari nilai dalam kolom yang dipilih dalam bingkai data panda dan hitung untuk pertanyaan yang berbeda namun terkait. Jawaban yang dipilih di sana menggunakandf1.groupby(['A','B']).size().reset_index().rename(columns={0:'count'})
Paul Rougieux

Jawaban:

198

pd.unique mengembalikan nilai unik dari array input, atau kolom atau indeks DataFrame.

Input untuk fungsi ini harus satu dimensi, sehingga beberapa kolom perlu digabungkan. Cara paling sederhana adalah dengan memilih kolom yang Anda inginkan dan kemudian melihat nilai-nilai dalam array NumPy rata. Seluruh operasi terlihat seperti ini:

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

Perhatikan bahwa ravel()ini adalah metode array daripada mengembalikan tampilan (jika mungkin) dari array multidimensi. Argumen 'K'memberitahu metode untuk meratakan array dalam urutan elemen disimpan dalam memori (panda biasanya menyimpan array yang mendasari dalam urutan Fortran-berdekatan ; kolom sebelum baris). Ini bisa lebih cepat secara signifikan daripada menggunakan urutan 'C' default metode.


Cara alternatif adalah memilih kolom dan meneruskannya ke np.unique:

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

Tidak perlu digunakan di ravel()sini karena metode ini menangani array multidimensi. Meski begitu, ini cenderung lebih lambat daripada pd.uniquekarena menggunakan algoritma berbasis semacam daripada hashtable untuk mengidentifikasi nilai-nilai unik.

Perbedaan kecepatan sangat penting untuk DataFrames yang lebih besar (terutama jika hanya ada beberapa nilai unik):

>>> 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
Alex Riley
sumber
2
Bagaimana Anda mendapatkan kembali bingkai data, bukan array?
Lisle
1
@ Lorong: kedua metode mengembalikan array NumPy, jadi Anda harus membangunnya secara manual, misalnya pd.DataFrame(unique_values),. Tidak ada cara yang baik untuk mendapatkan kembali DataFrame secara langsung.
Alex Riley
@ Lorong karena ia telah menggunakan pd.unique itu mengembalikan numpy.ndarray sebagai hasil akhir. Apakah ini yang Anda tanyakan?
Ash Upadhyay
1
@ Lorong, mungkin yang ini df = df.drop_duplicates (subset = ['C1', 'C2', 'C3'])?
tickly potato
14

Saya telah menyiapkan a DataFramedengan beberapa string sederhana di kolomnya:

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

Anda dapat menggabungkan kolom yang Anda minati dan memanggil uniquefungsi:

>>> pandas.concat([df['a'], df['b']]).unique()
array(['a', 'b', 'd', 'e', 'g', 'h'], dtype=object)
Mike
sumber
7
In [5]: set(df.Col1).union(set(df.Col2))
Out[5]: {'Bill', 'Bob', 'Joe', 'Mary', 'Steve'}

Atau:

set(df.Col1) | set(df.Col2)
James Little
sumber
1

Non- pandassolusi: menggunakan 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)

Keluaran:

   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'])
NullDev
sumber
1

bagi kita yang menyukai semua hal panda, berlaku, dan tentu saja fungsi lambda:

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

inilah cara lain


import numpy as np
set(np.concatenate(df.values))
muon
sumber
0
list(set(df[['Col1', 'Col2']].as_matrix().reshape((1,-1)).tolist()[0]))

Outputnya adalah ['Mary', 'Joe', 'Steve', 'Bob', 'Bill']

smishra
sumber