給定一個選擇器Series,即一個Series被視為一個DataFrame的查詢,即選擇器Series的索引是一個DataFrame中要查詢的行的子集,其值將在查詢中被匹配,目前,我正在做以下作業:
import pandas as pd
df = pd. DataFrame([{'a':1, 'b':2, 'c': 3},{'a:11,'b: 22,'c':33}, {'a: 1,'b':22,'c':333}] )
selector_series = pd.Series({'a'/span>:1,'b'/span>:22})
desired_df = df[pd.DataFrame([df[x]==selector_series[x] for x in selector_series.index.intersection(df.columns)]).all()]
print(desired_df)
輸出:
a b c
2 1 22 333
然而,我懷疑這種事情是一個足夠常見的操作,以至于有一個更 "Pandasic"(相對于Pythonic)的方式來做同樣的事情。 有嗎?
uj5u.com熱心網友回復:
對于pandas來說,一個更自然的方法不是使用回圈,而是使用eq方法來對公共索引進行比較:
idx = df.columns.intersection(selector_series.index)
df.loc[df[idx].eq(selector_series.loc[idx]).all(1)]
uj5u.com熱心網友回復:
像eq這樣的Pandas比較方法會執行一個對齊操作。這通常用于為 "外部 "比較進行對齊:
以這個修改過的例子為例。
拿這個修改過的例子來說吧
df = pd. DataFrame({'a'/span>: [1, 11, 1], 'b': [2, 22, 22], 'c'/span>: [3, 33, 333]})
selector_series = pd.Series({'a'/span>: 1, 'b': 22, 'd': 156})
df.eq(selector_series)
a b c d
0 True False False False False
1 False True False False
2 True True False False
注意到Series和DataFrame之間的列的union是如何被比較的。然而,在這種情況下,我們不希望這樣,因為c(只在DataFrame中)和d(只在Series中)只能是False。
相反,我們可以明確地
align來覆寫默認的how與'inner。
這里有一個輔助方法:
def intersection_eq(df_: pd.DataFrame, s_: pd.Series) -> pd.DataFrame:
aligned_df_, aligned_s_ = df_.align(s_, join='inner', axis=1, copy=False)
return aligned_df_.eq(aligned_s_)
現在,這個操作只回傳兩者中的共同列或交集。
intersection_eq(df, selector_series)
a b
0 True False
1 False True
2 True True
現在我們可以用all對axis=1進行典型過濾:
df[intersection_eq(df, selector_series).all(axis=1) ]
a b c
2 1 22 333
自然地,我們也可以把這個添加到我們的DataFrame定義中,或者創建一個DataFrame的子類,以允許更自然的語法:
def intersection_eq(df_: pd.DataFrame, s_: pd.Series) -> pd.DataFrame:
aligned_df_, aligned_s_ = df_.align(s_, join='inner', axis=1, copy=False)
return aligned_df_.eq(aligned_s_)
pd.DataFrame.intersection_eq = intersection_eq
這允許像這樣的用法:
df[df.intersection_eq(selector_series).all( axis=1) ]
a b c
2 1 22 333
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/332591.html
標籤:
