我正在處理一個結構為資料框架的數值串列,我想將這個串列中的每個數值與另一個資料框架(有點像下面這個)進行比較:
我正在處理一個結構為資料框架的數值串列。
Name Start End
藍色 10 28
紅色 23 25
綠色 89 107
紫色 168 216
黃色 21 40
現在讓我們假設值的串列是這樣的:
Name Value
W37
X176
Y43
Z96
對于 "值 "列中的每個元素,我想檢查該值是否包含在第一個資料框架的每個 "開始"-"結束 "范圍內,并將其添加到一個串列中(即 contained = [])。在這個例子中,W (37)包含在Yellow中,X (176)包含在Purple中,Z (96)包含在Green中,而Y不匹配,所以它將被排除(或添加到另一個串列not_contained = [])。
我怎樣才能做到這一點呢?謝謝大家。
uj5u.com熱心網友回復:
你可以把你的資料框架變成一個字典,然后為你的系列中的每個專案做一個查詢。
import pandas as pd
ser = pd. Series(index=list("WXYZ"), data=[37, 176, 43, 96], name="Value")
df = pd.DataFrame(
{
"Start": [10, 23, 89, 168, 21] 。
"Name": ["藍色", "紅色", "綠色", "紫色", "黃色"]。
"結束"。[28, 25, 107, 216, 40] 。
}
)
df_dict = df.set_index(["Start", "End"]) ["Name"].to_dict()
ser.apply(
lambda x: next(
(color for bounds, color in df_dict. items() if x in range(*bounds)), None None)
)
)
這就得到了
W Yellow
X 紫色
Y None物件
我們的想法是使df_dict成為一個字典,其鍵值為你的邊界:
{(10, 28) 。'Blue',
(23, 25) 。'Red',
(89, 107) 。'Green',
(168, 216) 。'Purple',
(21, 40) 。'Yellow'}。
然后回圈瀏覽你的系列,詢問每個元素x是否在邊界之間,使用的事實是
`
7 in range(3, 5)
# False[/span]。
7 in range(3,10)。
# 真
uj5u.com熱心網友回復:
由于沒有像sql或其他的運算子之間的連接,你可以在一個臨時鍵上交叉連接它們,然后過濾結果。
df['key'/span>] = 0
df2['key'] =0
df.merge(df2, on='key', how='outer') 。 query('Value >= Start & Value <= End').pop('Name_y') .tolist()
uj5u.com熱心網友回復:
你可以使用conditional_join從pyjanitor來模擬一個范圍連接,就像在SQL -> 注意,這是在dev:
# pip install git https://github.com/pyjanitor-devs/pyjanitor.git
import janitor
import pandas as pd
result = (df2.select_columns('Value')
.conditional_join(df1.select_columns('Start', 'End') 。
('Value'/span>, 'Start'/span>, '>=')。
('Value'/span>, 'End'/span>, '<=')。
how = 'left')
)
值 開始 結束
0 37 21.0[/span> 40.0[/span
1 176 168.0[/span> 216.0[/span
2 43 NaN NaN
3 96 89.0 107.0
根據Start或End中的空值,過濾為contained和not_contained:
contained = result.Value[result.Start.notna()].to_list()
not_contained = result.Value[~result.Start.notna()].to_list()
print(contained)
[37, 176, 96]
print(not_contained)
不過,在我看來,這樣做是矯枉過正,而且效率不高;你不需要資料框架,你只需要一些串列;一個更簡單的方法是使用Pandas的區間,再加上一個for-loop;對于大型資料框架,我希望這樣做更有效率:
# create intervalindex.
intervals = pd.IntervalIndex.from_arrays(df1.Start, df1.End, closed = 'both')
# 我們可以使用pandas get_indexer,。
# 然而,區間是重疊的,
# 而get_indexer只對非重疊/唯一的索引有效。
包含 = []
not_contained = []
for _, value in df2.Value.items()。
if intervals.contains(value).any()。
contained.append(value)
else:
not_contained.append(value)
print(contained)
[37, 176, 96]
print(not_contained)
[43]。
uj5u.com熱心網友回復:
作為一個松散的解決方案,你可以迭代一行并匹配值。我已經用上述方法創建了一個解決方案。
import pandas as pd
df = pd. DataFrame({'name': ['Blue'/span>, 'Red'/span>, 'Green'/span>, 'Purple'/span>, 'Yellow'/span>]。
'start': [10,23,89,168, 21] 。
'end'。 [28,25,107,216, 40]})
df2 = pd.DataFrame({'name':['W','X','Y','Z'] 。
'value':[37,176, 43, 96]})
包含=[]
not_contained = []
def checking(val)。
# iterate over df rows.
for index, row in df.iterrows() 。
if val >= row['start'] and val <= row['end'] 。
# 如果找到值,附加到包含的串列中并回傳。
contained.append(val)
return True
# 如果沒有找到值,將其追加到not_contained串列中。
not_contained.append(val)
# apply function
df2['value'].apply(checking)
print("contained: ",contained)
print("not_contained: ",not_contained)
輸出:
contained: [37, 176, 96]
not_contained: [43]
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/324002.html
標籤:
上一篇:為什么我的PandasDataFrame的值根據索引不按順序排列?
下一篇:使視圖后面的按鈕不能點擊
