簡體   English   中英

在執行排序條件時查找兩個列表或數據框之間的交集

[英]Finding an Intersection between two lists or dataframes while enforcing an ordering condition

我有兩個列表(來自兩個單獨的 pandas 數據幀的列)並且希望在保留順序或基於條件排序的同時找到兩個列表的交集。 考慮以下示例:

x = ['0 MO', '1 YR', '10 YR', '15 YR', '2 YR', '20 YR', '3 MO', '3 YR',
     '30 YR', '4 YR', '5 YR', '6 MO', '7 YR', '9 MO', 'Country']
y = ['Industry', '3 MO', '6 MO', '9 MO', '1 YR', '2 YR', '3 YR',
       '4 YR', '5 YR', '7 YR', '10 YR', '15 YR', '20 YR', '30 YR']

answer = set(x).intersection(y)

變量 answer 產生重疊列,但不保留順序。 有沒有辦法對解決方案進行排序,使得答案產生:

answer = ['3 MO', '6 MO', '9 MO', '1 YR', '2 YR', '3 YR',
          '4 YR', '5 YR', '7 YR', '10 YR', '15 YR', '20 YR',
          '30 YR']

即首先按月(“MO”)和整數對相交列表進行排序,然后按年(“YR”)及其整數排序?

或者,是否有 pandas 方法可以通過兩個重疊列的數據幀(保留或聲明順序)獲得相同的結果?

您可以簡單地使用列表推導:

[this_name for this_name in x if this_name in y]

[this_name for this_name in y if this_name in x]

我不知道您到底要做什么,但我的回答將針對您描述的用例。 如果您想使用 pandas,我認為以下代碼可以滿足您的需求。 如果您有更復雜的數據,我認為您可能需要將列類型更改為timedelta以獲得更大的靈活性。 在這種情況下排序是有效的,因為MO按字母順序排列在YR之前。

import pandas as pd
df1 = pd.DataFrame({'x': ['0 MO', '1 YR', '10 YR', '15 YR', '2 YR', '20 YR', '3 MO', '3 YR',
     '30 YR', '4 YR', '5 YR', '6 MO', '7 YR', '9 MO', 'Country']})
df2 = pd.DataFrame({'y': ['Industry', '3 MO', '6 MO', '9 MO', '1 YR', '2 YR', '3 YR',
       '4 YR', '5 YR', '7 YR', '10 YR', '15 YR', '20 YR', '30 YR']})

# drop 'non-standard' data 
df1["x"] = df1["x"].apply(lambda x: x if x[0].isdigit() else None)
df2["y"] = df2["y"].apply(lambda x: x if x[0].isdigit() else None)
df1.dropna(inplace=True)
df2.dropna(inplace=True)

# make two columns to sort 
df1["value"] = df1["x"].apply(lambda x: int(x[:-2]))
df1["unit"] = df1["x"].apply(lambda x: x[-2:])

df2["value"] = df2["y"].apply(lambda x: int(x[:-2]))
df2["unit"] = df2["y"].apply(lambda x: x[-2:])

# sort by unit and value
df1 = df1.sort_values(by=["unit", "value"]).drop("x", axis=1)
df2 = df2.sort_values(by=["unit", "value"]).drop("y", axis=1)

# merge 
df = pd.merge(df1, df2, on=["unit", "value"])
df["result"] = df.apply(lambda x: str(x["value"]) + " " + x["unit"], axis=1)
df.drop(["unit", "value"], axis=1, inplace=True)
df



使用列表推導來檢查x中的項目是否也存在於y的集合中。 這保留了每個項目出現在x中的順序,同時僅檢查y中的成員資格:

y_set = set(y)
answer = [item for item in x if item in y_set]

或使用filter完成基本相同的工作:

answer = list(filter(lambda i: i in y_set, x))

Output:

['1 YR', '10 YR', '15 YR', '2 YR', '20 YR', '3 MO', '3 YR', '30 YR', '4 YR', '5 YR', '6 MO', '7 YR', '9 MO']

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM