0

我有两个列表(来自两个单独的 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 方法可以通过两个重叠列的数据帧(保留或声明顺序)获得相同的结果?

4

3 回答 3

1

您可以简单地使用列表推导:

[this_name for this_name in x if this_name in y]

[this_name for this_name in y if this_name in x]
于 2022-01-08T14:41:00.287 回答
1

您可以通过将自定义函数作为键传递来使用sorted函数进行排序。answer由于您想首先按 MO 或 YR 排序,然后按整数值排序,因此您可以在空白处拆分并按第二部分(MO 或 YR)然后按第一部分的整数值进行评估。

def sorter(x):
    s = x.split()
    return (s[1],int(s[0]))

out = sorted(set(x).intersection(y), key=sorter)

输出:

['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']
于 2022-01-08T18:15:30.510 回答
0

我不知道您到底要做什么,但我的回答将针对您描述的用例。如果您想使用 pandas,我认为以下代码将满足您的需求。如果您有更复杂的数据,我认为您可能需要更改列类型以timedelta获得更大的灵活性。在这种情况下,排序是有效的,因为MO它是按字母顺序排列的 before 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



于 2022-01-08T15:07:14.213 回答