使用python计算2D数组中特定主项的多个项的出现次数

2024-09-27 21:31:12 发布

您现在位置:Python中文网/ 问答频道 /正文

我有2D列表,每行包含常用名称条目和附加信息。我想找出属于每个公共名称的MYFR元素的总数

For example, this is my list 
[['SOME TEXT', 'COMMON_NAME1', None, 'CHOC', 'MYFR01'],
['SOME TEXT2', 'COMMON_NAME1', None, 'ABC',  'MYFR02'], 
['SOME TEXT3', 'COMMON_NAME1', None, 'XYZ',  'MYFR03'],
['SOME TEXT4', 'COMMON_NAME2', None, 'XYZ',  'STRAWBERRY'],
['SOME TEXT5', 'COMMON_NAME2', None, 'XYZ',  'MYFR01'],
['SOME TEXT6', 'COMMON_NAME2', None, 'XYZ',  'MYFR02'],
['SOME TEXT7', 'COMMON_NAME2', None, 'XYZ',  'APPLE'] 

对于每个常用名称,如果它们位于{'MYFR01'、'MYFR02'、'MYFR03'中,我想找到发生次数的总和

这样在这个例子中,我想得到COMMON_NAME1=3和COMMON_NAME2=2

有没有一个简单的方法来实现这一点

多谢各位


Tags: 名称none信息元素列表条目somecommon
3条回答

您还可以使用pandas来执行以下操作:

import pandas as pd

df = pd.DataFrame(data, columns=['text', 'cname', 'none', 'code', 'name'])

         text         cname  none  code        name
0   SOME TEXT  COMMON_NAME1  None  CHOC      MYFR01
1  SOME TEXT2  COMMON_NAME1  None   ABC      MYFR02
2  SOME TEXT3  COMMON_NAME1  None   XYZ      MYFR03
3  SOME TEXT4  COMMON_NAME2  None   XYZ  STRAWBERRY
4  SOME TEXT5  COMMON_NAME2  None   XYZ      MYFR01
5  SOME TEXT6  COMMON_NAME2  None   XYZ      MYFR02
6  SOME TEXT7  COMMON_NAME2  None   XYZ       APPLE


df.loc[df['name'].str.contains('MYFR'), ['name', 'cname']] \
  .groupby('cname', as_index=False) \
  .count()

          cname  name
0  COMMON_NAME1     3
1  COMMON_NAME2     2

此外,我们还可以使用itertools:

from itertools import groupby

second = itemgetter(1)
last = itemgetter(-1)

for k, v in groupby(data, key=second):
    print(k, len([last(i) for i in v if last(i).startswith('MYFR')]))

COMMON_NAME1 3
COMMON_NAME2 2

这里唯一需要注意的是,必须首先对数据进行排序

我们将保留一个字典,将COMMON_NAME值映射到MYFR值集,然后在最后测量这些值集的大小。这决定了每个COMMON_NAME的唯一MYFR元素的数量

from collections import defaultdict

d = defaultdict(set)

for first, common_name, *others, last in my_list:
    if common_name.startswith("COMMON_NAME"):  # Maybe unneccessary
        if last.startswith("MYFR"):
            d[common_name].add(last)

d = {k: len(v) for k, v in d.items()}
# {'COMMON_NAME1': 3, 'COMMON_NAME2': 2}

下面是一个带有collections.Counter的解决方案:

>>> from collections import Counter
>>> data = [['SOME TEXT', 'COMMON_NAME1', None, 'CHOC', 'MYFR01'],
... ['SOME TEXT2', 'COMMON_NAME1', None, 'ABC',  'MYFR02'], 
... ['SOME TEXT3', 'COMMON_NAME1', None, 'XYZ',  'MYFR03'],
... ['SOME TEXT4', 'COMMON_NAME2', None, 'XYZ',  'STRAWBERRY'],
... ['SOME TEXT5', 'COMMON_NAME2', None, 'XYZ',  'MYFR01'],
... ['SOME TEXT6', 'COMMON_NAME2', None, 'XYZ',  'MYFR02'],
... ['SOME TEXT7', 'COMMON_NAME2', None, 'XYZ',  'APPLE']]

>>> c = Counter(i[1] for i in data if i[-1].startswith('MYFR'))
>>> c
Counter({'COMMON_NAME1': 3, 'COMMON_NAME2': 2})

这假设您的目标选择总是以MYFR开始。仔细阅读您的问题,您还可以使用:

>>> tgt = {'MYFR01', 'MYFR02', 'MYFR03'}
>>> c = Counter(i[1] for i in data if i[-1] in tgt)
>>> c
Counter({'COMMON_NAME1': 3, 'COMMON_NAME2': 2})

关于^{}(一个dict的子类)的好处是它可以接受一个generator expression。这意味着您不需要将“过滤”项具体化为一些中间数据结构,例如列表

相关问题 更多 >

    热门问题