【问题标题】:csv import - how to ingeniously check that the name of columns are "correct"?csv import - 如何巧妙地检查列名是否“正确”?
【发布时间】:2022-01-21 11:54:53
【问题描述】:

我正在尝试根据手动写入 csv 的数据对电网进行建模。 例如,我有一个应该称为'DEPART 1' 的列。 我经常可以找到'Départ 1''DEP1''depart 1'' DEPART 1 ' 或许多其他可能性...

知道,我是用 :

导入的
import_net_data = pd.read_excel(path_file, sheet_name=None)

我希望能够识别接近“正式名称”的列(可能通过忽略空格,maj ...)

有没有正确的方法:

  • 替换任何不正确的字符串(不提供所有 可能性)由正确的人
  • 检查那些列名是否只出现一次

【问题讨论】:

  • 到目前为止您尝试过什么?如果不至少检查一组不同的可能性,我不确定这会有多容易。
  • “许多其他可能性...”,例如...还有多少、2 倍、10 倍的可能性?
  • 这似乎是一个后验问题......如果你没有告诉我“正式名称”,我作为一个人类怎么会(无限聪明比一个计算机)原因这 4 个示例都应该等同于 DEPART 1?您是如何得出“正式名称”的:您自己的推理、统计推断,还是其他方式?

标签: python string dataframe csv replace


【解决方案1】:

您需要在这里使用模糊字符串匹配。对于 python,作为一个选项,您可以查看 thefuzz 包,它为字符串计算 Levenshtein distance

举个例子:

from thefuzz import fuzz


st = 'DEPART 1'
strs = [ 'Départ 1', 'DEP1','depart 1',' DEPART 1 ']

for s in strs:
    l_d= fuzz.ratio(st.lower(), s.lower()) # Levenshtein distance
    print(st, s, '|', 'Levenshtein distance: ', l_d, 'is the same: ', l_d > 60)

输出:

DEPART 1 Départ 1 | Levenshtein distance:  88   is the same:  True
DEPART 1 DEP1     | Levenshtein distance:  67   is the same:  True
DEPART 1 depart 1 | Levenshtein distance:  100  is the same:  True
DEPART 1 DEPART 1 | Levenshtein distance:  89   is the same:  True

查看更多信息:https://www.datacamp.com/community/tutorials/fuzzy-string-python

使用它你可以实现你的目标。

“替换任何不正确的字符串”

import pandas as pd
from thefuzz import fuzz

st = 'DEPART 1'

df = pd.DataFrame(columns=['DEPART 1','DEP1','depart 1','depart 1','not even close'])
print(df)

cols = []
for column in df.columns:
    if fuzz.ratio(st.lower(), column.lower()) > 60:
        cols.append(st)
    else:
        cols.append(column)

df.columns = cols

print(df)

输出:

Columns: [DEPART 1, DEP1, depart 1, depart 1, not even close]
Columns: [DEPART 1, DEPART 1, DEPART 1, DEPART 1, not even close]

“检查列名的出现”

import pandas as pd
import collections

df = pd.DataFrame(columns=['DEPART 1','DEP1','depart 1','depart 1','not even close'])

print(collections.Counter(df.columns))

输出:

Counter({'depart 1': 2, 'DEPART 1': 1, 'DEP1': 1, 'not even close': 1})

【讨论】:

    【解决方案2】:

    我建议你使用正则表达式来识别这些列名之间合适的模式,并将它们替换为正式名称。

    您可以使用re library 来执行此操作。将其与 regex101 website 结合使用,以找到适合所有情况的最佳正则表达式。

    这里有一个解决这个特殊情况的小代码示例:

    import re
    
    official_name = "depart 1"
    
    column_names = [
        "Départ 1",
        "DEP1",
        "depart 1",
        " DEPART 1 ",
        " depart      1"]
        
    regex = "\s*[d^D][e^E^é^É][p^P]\D*\s*1\s*"
    
    for name in column_names:
        print(name)
        result = re.search(regex, name)
        if result:
            print("Replace with {0}".format(official_name))
        else:
            print("Could not find the regex pattern")
    

    它输出这个:

    Départ 1
    Replace with depart 1
    DEP1
    Replace with depart 1
    depart 1
    Replace with depart 1
     DEPART 1 
    Replace with depart 1
     depart      1
    Replace with depart 1
    

    【讨论】:

    • 非常感谢,这完全有效!
    猜你喜欢
    • 2012-02-05
    • 1970-01-01
    • 1970-01-01
    • 2012-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-11
    相关资源
    最近更新 更多