【问题标题】:How to calculate the number of matching elements in a list (as a pandas column) in another list如何计算另一个列表中的列表(作为熊猫列)中匹配元素的数量
【发布时间】:2020-01-18 03:07:20
【问题描述】:

经过多次失败的尝试,我正在寻求帮助来解决这个问题。说,我有一个清单

target = [1990, 1991, 1992, 1993, 1994]

和一个数据框stnYrs as

STATION        YEARS
A             [1990,1994,1995,1996,1998,2000]
B             [1992,1995,2001]
C             [1988,1989]

我想在stnYrs 中创建一个新列NYEAR,作为在target 中找到的YEARS 列中的匹配年数。这样做的pythonic方法是什么? 结果应该是这样的

STATION        YEARS                           NYEAR
A             [1990,1994,1995,1996,1998,2000]  2
B             [1992,1995,2001]                 1
C             [1988,1989]                      0

编辑 1 -

我尝试了 Chris 和 YO 建议的方法。如果我对targetstnYrs 使用测试示例,两者都可以工作。但是,在我的实际应用中,都没有给出正确的答案。对于NYEAR,我总是得到零。我只是不知道为什么。以下是我的代码中的几行:

stnYrs = pd.read_csv('isd_stnNyr_duOnly.txt',dtype={'STATION':'str'})
periods = [(1971,1980),(1981,1990),(1991,2000),(2001,2010)]
for iperd, perd in enumerate(periods):
    ybgn, yend = perd
    target = list(range(ybgn,yend+1))
    stnYrs['NYEAR'] = stnYrs['YEARS'].apply(lambda x: sum(1 for yr in x if yr in target))
    ...

stnYrs[['STATION','YEARS','NYEAR']].head()给了

台年 NYEAR
0 78982099999 [1959, 1960, 1974, 1975, 1976...] 0

1 69205499999 无 0

2 40941099999 [1976, 1977, 1978] 0

3 40942099999 [1976, 1977, 1978, 1979, 1980...] 0

isd_stnNyr_duOnly.txt 文件看起来像

站、国家、组、来源、纬度、经度、海拔、年 78982099999,AA,SAM,4,12.501,-70.015,18.28,"[1959, 1960, 1974, 1975, 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1993, 1997, 1998, 1999, 2000, 2001, 2004, 2008]"

69205499999,AF,SAS,4,32.8,67.633,1989.0,na

40941099999,AF,SAS,4,34.883,65.3,2070.0,"[1976, 1977, 1978]"

40942099999,AF,SAS,4,33.533,65.267,2183.0,"[1976, 1977, 1978, 1979, 1980, 1981, 1983, 1984, 2010, 2019]"

编辑 2-

我终于想出了如何将YEARS 列转换为列表。

def clean(seq_string): return list(map(int, seq_string.strip("[]").split(',')))

stnrec = pd.read_csv('isd_stnNyr_duOnly.txt',dtype={'STATION':'str'},converters={'YEARS': clean})

【问题讨论】:

  • stnYrs["NYEAR"] = stnYrs["YEARS"].apply(lambda x: np.intersect1d(x,target).size) ?
  • @thushv89 如果YEARS 包含重复的年份,这可能会失败
  • 您的'YEARS' 列实际上是一个字符串。您必须提供dtype={'STATION':'str', 'YEARS': 'list'})
  • 我感觉数据类型可能是问题所在,但在这种情况下,'YEARS': 'list' 不起作用。得到错误data type "list" not understood
  • @Xin 在list 周围不加引号尝试同样的事情。

标签: python python-3.x pandas list


【解决方案1】:

让我们做吧

stnYrs['NYEAR']=pd.DataFrame(stnYrs["YEARS"].tolist()).isin(target).sum(1).values

【讨论】:

  • 很好,这适用于测试示例,但由于其他原因不适用于我的代码。我想知道为什么(请参阅我的编辑)。
  • 很抱歉,这个解决方案大约是@Chris 提出的解决方案的 450%。
【解决方案2】:

pandas.DataFrame.apply与内置sum一起使用:

stnYrs['NYEAR'] = stnYrs['YEARS'].apply(lambda x: sum(1 for i in x if i in target))
print(stnYrs)

输出:

  STATION                                 YEARS  NYEAR
0       A  [1990, 1994, 1995, 1996, 1998, 2000]      2
1       B                    [1992, 1995, 2001]      1
2       C                          [1988, 1989]      0

【讨论】:

  • 很好,这适用于测试示例,但由于其他原因不适用于我的代码。我想知道为什么(请参阅我的编辑)。
猜你喜欢
  • 2019-02-14
  • 1970-01-01
  • 1970-01-01
  • 2017-04-21
  • 2020-07-24
  • 2020-09-01
  • 2021-07-28
  • 2020-06-12
  • 2020-09-20
相关资源
最近更新 更多