pandaların benzersiz değerleri birden çok sütun


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

'Sütun1' ve 'Sütun2'nin benzersiz değerlerini döndürmenin en iyi yolu nedir?

İstenilen çıktı

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

3
Pandalar veri çerçevesindeki seçili sütunlardaki benzersiz değer kombinasyonlarına da bakın ve farklı ancak ilişkili bir soru için sayın . Orada seçilen cevap kullanılıyordf1.groupby(['A','B']).size().reset_index().rename(columns={0:'count'})
Paul Rougieux

Yanıtlar:


199

pd.unique bir girdi dizisinden veya DataFrame sütunundan veya dizinden benzersiz değerleri döndürür.

Bu işlevin girdisinin tek boyutlu olması gerekir, bu nedenle birden çok sütunun birleştirilmesi gerekir. En basit yol, istediğiniz sütunları seçmek ve ardından değerleri düzleştirilmiş bir NumPy dizisinde görüntülemektir. Tüm operasyon şöyle gözüküyor:

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

ravel()Çok boyutlu bir dizinin bir görünümünü (mümkünse) döndüren bir dizi yöntemi olduğuna dikkat edin. Argüman 'K', yönteme, öğelerin bellekte saklandığı sıraya göre diziyi düzleştirmesini söyler (pandalar genellikle alttaki dizileri Fortran-bitişik sırayla depolar ; sütunlar satırlardan önce). Bu, yöntemin varsayılan 'C' sırasını kullanmaktan önemli ölçüde daha hızlı olabilir.


Alternatif bir yol, sütunları seçip şunlara iletmektir np.unique:

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

Kullanmaya gerek yok ravel()Yöntem çok boyutlu dizileri işlediği burada . Öyle bile olsa, bu, pd.uniquebenzersiz değerleri tanımlamak için bir hashtable yerine sıralama tabanlı bir algoritma kullandığından muhtemelen daha yavaş olacaktır .

Hızdaki fark, daha büyük DataFrame'ler için önemlidir (özellikle yalnızca birkaç benzersiz değer varsa):

>>> 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
Bir dizi yerine bir veri çerçevesini nasıl geri alırsınız?
Lisle

1
@Lisle: her iki yöntem de bir NumPy dizisi döndürür, bu nedenle onu manuel olarak oluşturmanız gerekir, örn pd.DataFrame(unique_values). Bir DataFrame'i doğrudan geri almanın iyi bir yolu yoktur.
Alex Riley

@Lisle pd.unique kullandığından son çıktı olarak bir numpy.ndarray döndürür. Sorduğun bu muydu?
Kül Upadhyay

1
@Lisle, belki bu df = df.drop_duplicates (alt küme = ['C1', 'C2', 'C3'])?
gıcırtılı patates

14

DataFrameSütunlarında birkaç basit dizeyle bir kurdum :

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

İlgilendiğiniz sütunları birleştirebilir ve uniqueişlevi çağırabilirsiniz :

>>> 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'}

Veya:

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


1

Non pandasçözeltisi: kullanılmasında ().

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)

Çıktı:

   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

pandaları, uygulayan ve tabii ki lambda işlevlerini seven bizler için:

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

1

işte başka bir yol


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

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

Çıktı ['Mary', 'Joe', 'Steve', 'Bob', 'Bill'] olacaktır

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.