จะ "เลือกเฉพาะ" ในคอลัมน์กรอบข้อมูลหลายคอลัมน์ในแพนด้าได้อย่างไร


110

ฉันกำลังมองหาวิธีทำเทียบเท่ากับ SQL

SELECT DISTINCT col1, col2 FROM dataframe_table

การเปรียบเทียบ sql ของแพนด้าไม่มีอะไรเกี่ยวกับdistinct.

.unique() ใช้ได้กับคอลัมน์เดียวเท่านั้นดังนั้นฉันคิดว่าฉันสามารถต่อคอลัมน์หรือวางไว้ในรายการ / ทูเพิลและเปรียบเทียบแบบนั้น แต่ดูเหมือนว่าแพนด้าควรทำในลักษณะที่เป็นธรรมชาติมากกว่า

ฉันพลาดอะไรบางอย่างที่ชัดเจนหรือไม่มีทางทำเช่นนี้?


คุณต้องทำบางอย่างเช่นdf.apply(pd.Series.unique)นี้ แต่จะไม่ได้ผลหากจำนวนของค่าที่ไม่ซ้ำกันแตกต่างกันไปในแต่ละคอลัมน์ดังนั้นคุณต้องสร้างคำสั่งของชื่อคอลัมน์เป็นคีย์และค่าที่ไม่ซ้ำกันเป็นค่า
EdChum

คำตอบ:


183

คุณสามารถใช้drop_duplicatesวิธีการรับแถวที่ไม่ซ้ำกันใน DataFrame:

In [29]: df = pd.DataFrame({'a':[1,2,1,2], 'b':[3,4,3,5]})

In [30]: df
Out[30]:
   a  b
0  1  3
1  2  4
2  1  3
3  2  5

In [32]: df.drop_duplicates()
Out[32]:
   a  b
0  1  3
1  2  4
3  2  5

คุณสามารถระบุsubsetอาร์กิวเมนต์คำหลักได้หากคุณต้องการใช้เฉพาะบางคอลัมน์เพื่อกำหนดความเป็นเอกลักษณ์ ดูdocstring


5
อาจเป็นที่น่าสังเกตว่าdf.drop_duplicates()โดยค่าเริ่มต้นไม่ใช่วิธีการแทนที่ดังนั้นจึงส่งคืน DataFrame ใหม่ ( dfไม่เปลี่ยนแปลง) นี่เป็นพฤติกรรมมาตรฐานที่เป็นธรรม แต่ก็ยังอาจเป็นประโยชน์ได้
evophage

15

ฉันได้ลองวิธีแก้ปัญหาต่างๆแล้ว อันดับแรกคือ:

a_df=np.unique(df[['col1','col2']], axis=0)

และทำงานได้ดีสำหรับข้อมูลที่ไม่ใช่วัตถุอีกวิธีหนึ่งในการทำเช่นนี้และเพื่อหลีกเลี่ยงข้อผิดพลาด (สำหรับประเภทคอลัมน์ออบเจ็กต์) คือการใช้ drop_duplicates ()

a_df=df.drop_duplicates(['col1','col2'])[['col1','col2']]

คุณยังสามารถใช้ SQL เพื่อทำสิ่งนี้ได้ แต่มันทำงานช้ามากในกรณีของฉัน:

from pandasql import sqldf
q="""SELECT DISTINCT col1, col2 FROM df;"""
pysqldf = lambda q: sqldf(q, globals())
a_df = pysqldf(q)

7

ไม่มีuniqueเมธอดสำหรับ df หากจำนวนค่าที่ไม่ซ้ำกันสำหรับแต่ละคอลัมน์เหมือนกันสิ่งต่อไปนี้จะใช้ได้: df.apply(pd.Series.unique)แต่ถ้าไม่เช่นนั้นคุณจะได้รับข้อผิดพลาด อีกวิธีหนึ่งคือการจัดเก็บค่าในรูปแบบที่กำหนดไว้ในชื่อคอลัมน์:

In [111]:
df = pd.DataFrame({'a':[0,1,2,2,4], 'b':[1,1,1,2,2]})
d={}
for col in df:
    d[col] = df[col].unique()
d

Out[111]:
{'a': array([0, 1, 2, 4], dtype=int64), 'b': array([1, 2], dtype=int64)}

เป็นไปได้ไหมที่จะตรวจสอบความไม่ซ้ำกันสำหรับหลายคอลัมน์
Anoop D

ได้รับคำตอบจากคำถาม SO อื่นโดยใช้ numpynp.unique(df[['column1','column2']].values)
Anoop D

7

เพื่อแก้ปัญหาที่คล้ายกันฉันใช้groupby:

print(f"Distinct entries: {len(df.groupby(['col1', 'col2']))}")

ความเหมาะสมจะขึ้นอยู่กับสิ่งที่คุณต้องการทำกับผลลัพธ์หรือไม่ (ในกรณีของฉันฉันแค่ต้องการให้เทียบเท่าCOUNT DISTINCTตามที่แสดง)



-1

คุณสามารถนำชุดของคอลัมน์และลบชุดที่เล็กกว่าออกจากชุดใหญ่:

distinct_values = set(df['a'])-set(df['b'])
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.