【问题标题】:How do I count the occurencies of a word in csv file under conditions?如何在条件下计算 csv 文件中某个单词的出现次数?
【发布时间】:2021-04-09 09:59:25
【问题描述】:

我有一个这样的 data.csv 文件(其中数据是单词)

data
data1|data2|data3
data1|data2
data1|data4|data6
data2|data3
data4|data5|data6
data4
data5|data7

我想读取 data1 出现的次数(例如)何时 data2 出现。因此,当我想在它们之间形成关系时,两个数据在行中何时以及多少次共存。我知道 counter 方法,但我对仅计算数据实例不感兴趣。

我该如何解决这个问题?我是使用 pd 创建数据框还是使用列表?

(编辑:data.csv 中的最大列数为 6)

所需的输出类似于:

data1-data2: 2
data1-data3: 1
data1-data4: 1
data1-data5: 0 
etc

保存到 CSV 文件中

【问题讨论】:

  • 嗨史蒂文,到目前为止你尝试了什么?你能包括你目前的方法吗?
  • 我没有什么要展示的。我试图将我的 csv 转换为 6 列的数据框,然后将其转换为 2d 列表并使用条件来读取它,但它失败了。我没有解析数据的经验,所以我来到这里。
  • 下面使用itertools的答案相当优雅
  • 您能否提供此示例数据的完整所需输出?您正在寻找的相关性存在很多歧义。
  • 是的,我知道这看起来很混乱。例如:data4-data5 结果应为 1。对于 data5-data4,所需结果也应为 1,尽管不是按该顺序包含此组合的行

标签: python pandas list dataframe count


【解决方案1】:

让我们试试get_dummiescombinations

from itertools import combinations

df = pd.read_csv('data.csv')
d = df['data'].str.get_dummies('|')

dct = {}
for x, y in combinations(g, r=2):
    dct[f'{x}:{y}'] = d[[x, y]].eq(1).all(1).sum()

# or with dict comprehension
# {'{}:{}'.format(*v): d[[*v]].eq(1).all(1).sum() for v in combinations(g, r=2)}

详情:

首先将csv文件读取为pandas数据框:

print(df)
                data
0  data1|data2|data3
1        data1|data2
2  data1|data4|data6
3        data2|data3
4  data4|data5|data6
5              data4
6        data5|data7

data 中的值编码为虚拟/指标列:

print(d)
   data1  data2  data3  data4  data5  data6  data7
0      1      1      1      0      0      0      0
1      1      1      0      0      0      0      0
2      1      0      0      1      0      1      0
3      0      1      1      0      0      0      0
4      0      0      0      1      1      1      0
5      0      0      0      1      0      0      0
6      0      0      0      0      1      0      1

生成指标列的combinations 并使用dict 将它们的出现频率存储在一起:


print(dct)
{'data1:data2': 2,
 'data1:data3': 1,
 'data1:data4': 1,
 'data1:data5': 0,
 'data1:data6': 1,
 'data1:data7': 0,
 'data2:data3': 2,
  ...
  ...
 'data5:data7': 1,
 'data6:data7': 0}

【讨论】:

  • 漂亮而优雅的解决方案。但是,您可能希望扩展该 dict 理解,因为它可能很难阅读和理解,尤其是考虑到这是一个帮助经验不足的开发人员而不是编写高尔夫代码的网站。
  • @HubertGrzeskowiak 谢谢你的建议:)..但是恕我直言,在扩展了更多代码行之后......
  • 额外的代码行是一件好事,如果它们有助于理解并使代码更容易编辑。
  • 它显示 NameError: name 'g' is not defined @ShubhamSharma
  • @HubertGrzeskowiak 没问题..编辑了答案
【解决方案2】:

这个问题非常模棱两可,因此有很多不同的答案。我在这里假设您的意思是计算第一列和以下任何列的组合。

import csv
from collections import Counter

counter = Counter()
with open('data.csv') as csvfile:
  reader = csv.reader(csvfile, delimiter='|')
  for line in reader:
    if line[0]:
      for fragment in line[1:]:
        entry = line[0] + '-' + fragment
        counter.update({entry: 1})

print(counter)

输出:

Counter({'data1-data2': 2, 'data1-data3': 1, 'data1-data4': 1, 'data1-data6': 1, 'data2-data3': 1, 'data4-data5': 1, 'data4-data6': 1, 'data5-data7': 1})

编辑 1:

假设您想要现有数据字段的任何非零组合:

import csv
from collections import Counter
from itertools import combinations

counter = Counter()
with open('data.csv') as csvfile:
  reader = csv.reader(csvfile, delimiter='|')
  for line in reader:
    counter.update(combinations(line, 2))

print(counter)

输出:

Counter({('data1', 'data2'): 2, ('data2', 'data3'): 2, ('data4', 'data6'): 2, ('data1', 'data3'): 1, ('data1', 'data4'): 1, ('data1', 'data6'): 1, ('data4', 'data5'): 1, ('data5', 'data6'): 1, ('data5', 'data7'): 1})

编辑 2: 假设您希望每个数据单元格与其他数据单元格相结合,包括那些不在同一行的任何位置显示的关系:

import csv
from collections import Counter
from itertools import combinations

counter = Counter()
unique = set()
with open('data.csv') as csvfile:
  reader = csv.reader(csvfile, delimiter='|')
  for line in reader:
    unique.update(line)
    counter.update(combinations(line, 2))
counter.update({entry: 0 for entry in combinations(unique, 2)})
print(counter)

输出:

Counter({('data1', 'data2'): 2, ('data2', 'data3'): 2, ('data4', 'data6'): 2, ('data1', 'data3'): 1, ('data1', 'data4'): 1, ('data1', 'data6'): 1, ('data4', 'data5'): 1, ('data5', 'data6'): 1, ('data5', 'data7'): 1, ('data7', 'data5'): 0, ('data7', 'data2'): 0, ('data7', 'data4'): 0, ('data7', 'data6'): 0, ('data7', 'data1'): 0, ('data7', 'data'): 0, ('data7', 'data3'): 0, ('data5', 'data2'): 0, ('data5', 'data4'): 0, ('data5', 'data1'): 0, ('data5', 'data'): 0, ('data5', 'data3'): 0, ('data2', 'data4'): 0, ('data2', 'data6'): 0, ('data2', 'data1'): 0, ('data2', 'data'): 0, ('data4', 'data1'): 0, ('data4', 'data'): 0, ('data4', 'data3'): 0, ('data6', 'data1'): 0, ('data6', 'data'): 0, ('data6', 'data3'): 0, ('data1', 'data'): 0, ('data', 'data3'): 0})

【讨论】:

  • 很抱歉没有更好地措辞。我实际上关心两个数据之间的任何类型的组合。这就是我所说的“共存”。列的顺序无关紧要,但感谢您的解决方案!
  • @Steven 这是一个有趣的练习!我根据您可能的意思添加了其他示例:D
  • 很高兴你喜欢它。顺便问一下,可以跳过文件头吗?
  • @Steven 您是在谈论 CSV 文件中的标题吗?这实际上取决于您是否有有效的标题。您帖子中的示例数据没有有效的标题 - 它需要为每列定义一个名称。如果你只是想跳过文件的第一行,你可以在启动阅读器之前添加next(csvfile)
  • 我只是想跳过第一行(就像一个魅力)thx
【解决方案3】:

尝试以下方法:

import itertools

with open('yourfile.csv') as f:
    l=f.readlines()

l=[i[:-1] for i in l[:-1]] + [l[-1]] #remove '\n' at the end

res={}

for i in l:
    temp=i.split('|')
    pairs=[k for k in itertools.combinations(temp, 2)]
    for j in pairs:
        if j in res:
            res[j]+=1
        elif j[::-1] in res:
            res[j[::-1]]+=1
        else:
            res[j]=1

输出:

>>>print(res)

{('data1', 'data2'): 2, ('data1', 'data3'): 1, ('data2', 'data3'): 2, ('data1', 'data4'): 1, ('data1', 'data6'): 1, ('data4', 'data6'): 2, ('data4', 'data5'): 1, ('data5', 'data6'): 1, ('data5', 'data7'): 1}

如果您想要出现 0 次的对,您可以执行以下操作:

s={i for j in res.keys() for i in j}

allpairs=[i for i in itertools.combinations(s,2)]

for i in allpairs:
    if i not in res and (i[1], i[0]) not in res:
        res[i]=0

【讨论】:

    猜你喜欢
    • 2023-04-04
    • 2010-11-26
    • 2019-09-01
    • 2021-01-11
    • 2011-06-20
    • 1970-01-01
    • 2017-08-14
    • 1970-01-01
    相关资源
    最近更新 更多