将Python包用于从类似CSV的文件中去除常见杂乱
项目描述
✂️ CSV Trimming
CSV Trimming是一个Python包,旨在将混乱的CSV文件(例如从网站抓取、旧系统或管理不善的数据中获得)转换为仅用一行代码即可清洁、格式良好的CSV文件。无需复杂的设置或大型语言模型。它简单、直接,通常可以完成工作。
如何安装此包?
像往常一样,只需使用pip下载它
pip install csv_trimming
如何使用此包?
此包非常简单易用,只需加载您的CSV并将其传递给修剪器。
import pandas as pd
from csv_trimming import CSVTrimmer
# Load your csv
csv = pd.read_csv("tests/documents/noisy/sicilia.csv")
# Instantiate the trimmer
trimmer = CSVTrimmer()
# And trim it
trimmed_csv = trimmer.trim(csv)
# That's it!
例如,您要清理的输入CSV在开始时可能看起来像这样
0 | 1 | 2 | 3 | 4 | |
---|---|---|---|---|---|
0 | #RIF! | #RIF! | ......... | /// | ----- |
1 | ('surname',)('-',)(0,) | region | (""('surname',)('-',)(0,"),)(' ',)(1,) | province | surname |
2 | ------ | #RIF! | #RIF! | ||
3 | #RIF! | Calabria | ------- | Catanzaro | Rossi |
4 | 0 | Sicilia | _____ | Ragusa | Pinna |
5 | "" | Lombardia | ------ | Varese | Sbrana |
6 | 0 | Lazio | __ | Roma | Mair |
7 | _ | Sicilia | #RIF! | Messina | Ferrari |
8 | ----- | .. | "" | 0 | --------- |
修剪后,它将看起来像这样
region | province | surname | |
---|---|---|---|
0 | Calabria | Catanzaro | Rossi |
1 | Sicilia | Ragusa | Pinna |
2 | Lombardia | Varese | Sbrana |
3 | Lazio | Roma | Mair |
4 | Sicilia | Messina | Ferrari |
魔法!
具有行相关性的高级修剪
有时,您正在处理的CSV可能具有行相关性,这意味着给定行的一部分被插入到下一行。这种情况通常发生在数据录入员希望将整个表格放入他们的屏幕上,并为了这样做,他们将行分成两部分时。虽然这显然是一种极其糟糕的做法,但在现实生活中确实会发生,CSV修剪器可以在一点点帮助下处理这种情况。
您只需要提供一个函数来定义哪些行是相关的,CSV Trimmer 会处理其余部分。虽然在这个例子中我们使用了相对简单的函数和相对干净的 CSV 文件,但该包可以处理更复杂的情况。
from typing import Tuple
import pandas as pd
from csv_trimming import CSVTrimmer
def simple_correlation_callback(
current_row: pd.Series,
next_row: pd.Series
) -> Tuple[bool, pd.Series]:
"""Return the correlation between two rows.
Parameters
----------
current_row : pd.Series
The current row being analyzed in the DataFrame.
next_row : pd.Series
The next row in the DataFrame.
Returns
-------
Tuple[bool, pd.Series]
A tuple with a boolean indicating if the rows are correlated
and a Series with the merged row.
"""
# All of the rows that have a subsequent correlated row are
# non-empty, and the subsequent correlated rows are always
# with the first cell empty.
if pd.isna(next_row.iloc[0]) and all(pd.notna(current_row)):
return True, pd.concat(
[
current_row,
pd.Series({"surname": next_row.iloc[-1]}),
]
)
return False, current_row
csv = pd.read_csv("tests/test.csv")
trimmer = CSVTrimmer(simple_correlation_callback)
result = trimmer.trim(csv)
在这种情况下,我们的 CSV 文件在开始时看起来是这样的
region | province | |
---|---|---|
0 | Campania | Caserta |
1 | Ferrero | |
2 | Liguria | Imperia |
3 | Conti | |
4 | Puglia | Bari |
5 | Fabris | |
6 | Sardegna | Medio Campidano |
7 | Conti | |
8 | Lazio | Roma |
9 | Fabbri |
修剪后,它将看起来像这样
region | province | surname | |
---|---|---|---|
0 | Campania | Caserta | Ferrero |
1 | Liguria | Imperia | Conti |
2 | Puglia | Bari | Fabris |
3 | Sardegna | Medio Campidano | Conti |
4 | Lazio | Roma | Fabbri |
更多示例
以下是一些该包实际应用的示例。
具有重复模式的案例
有时,当以较差的方式链式连接多个 CSV 文件时,您可能会遇到重复的模式。CSV Trimmer 会检测到与检测到的标题匹配的行,并且可以(可选)删除它们。
import pandas as pd
from csv_trimming import CSVTrimmer
# Load your csv
csv = pd.read_csv("tests/documents/noisy/duplicated_schema.csv")
# Instantiate the trimmer
trimmer = CSVTrimmer()
# And trim it
trimmed_csv = trimmer.trim(csv, drop_duplicated_schema=True)
# That's it!
例如,您要清理的输入CSV在开始时可能看起来像这样
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | |
---|---|---|---|---|---|---|---|---|
0 | #RIF! | //// | #RIF! | #RIF! | 0 | .... | 0 | 0 |
1 | ('surname',)('.',)(0,) | region | province | surname | ('province',)('_',)(1,) | 0 | ||
2 | 0 | //////// | region | province | surname | 0 | 0 | |
3 | _____ | /////// | region | province | surname | #RIF! | #RIF! | |
4 | Puglia | Bari | Zanetti | 0 | -------- | |||
5 | 0 | Piemonte | Alessandria | Fabbri | ||||
6 | 0 | ------- | #RIF! | #RIF! | 0 | ---- | ||
7 | ///////// | ///////// | Sicilia | Agrigento | Ferretti | ////////// | ---------- | |
8 | __ | -------- | Campania | Napoli | Belotti | /// | ||
9 | -------- | 0 | ///// | --- | 0 | ///// | ---------- | |
10 | ----- | #RIF! | Liguria | Savona | Casini | 0 | #RIF! | |
11 | ... | 0 | ----- | -------- | 0 | 0 |
修剪后,它将看起来像这样
region | province | surname | |
---|---|---|---|
0 | Puglia | Bari | Zanetti |
1 | Piemonte | Alessandria | Fabbri |
2 | Sicilia | Agrigento | Ferretti |
3 | Campania | Napoli | Belotti |
4 | Liguria | Savona | Casini |
只有填充的案例
有时,数据录入员可能会从左上角开始填写表格,并将其导出为周围也包含空单元格的表格。我们称这样的单元格为“填充”。CSV Trimmer 可以检测并删除它们。
import pandas as pd
from csv_trimming import CSVTrimmer
# Load your csv
csv = pd.read_csv("tests/documents/noisy/padding.csv")
# Instantiate the trimmer
trimmer = CSVTrimmer()
# And trim it
trimmed_csv = trimmer.trim(csv, drop_padding=True)
例如,您要清理的输入CSV在开始时可能看起来像这样
region | province | surname | ||
---|---|---|---|---|
0 | ||||
1 | ||||
2 | region | province | surname | |
3 | Campania | Caserta | Ferrero | |
4 | Liguria | Imperia | Conti | |
5 | Puglia | Bari | Fabris | |
6 | Sardegna | Medio Campidano | Conti | |
7 | Lazio | Roma | Fabbri | |
8 | ||||
9 | ||||
10 | ||||
11 |
修剪后,它将看起来像这样
region | province | surname | |
---|---|---|---|
0 | Campania | Caserta | Ferrero |
1 | Liguria | Imperia | Conti |
2 | Puglia | Bari | Fabris |
3 | Sardegna | Medio Campidano | Conti |
4 | Lazio | Roma | Fabbri |
命令行界面
该包还提供了一个命令行界面来修剪 CSV 文件。它包含在包的 setup.py
中,因此安装完该包后,您可以从命令行立即使用它。
您可以通过运行以下命令来使用它
csv-trim tests/documents/noisy/sicilia.csv tests/documents/noisy/sicilia_trimmed.csv
它支持以下选项以防止尝试某些修剪
--keep-padding
:不要尝试删除填充。--keep-duplicated-schema
:不要尝试删除重复的模式。--no-restore-header
:不要尝试恢复标题。
例如
csv-trim tests/documents/noisy/sicilia.csv tests/documents/noisy/sicilia_trimmed.csv --keep-padding
我如何为这个包做出贡献?
如果您发现了该包无法处理的某些新的边缘情况,或者您有一些建议的新功能,请随时提出问题。如果您想通过代码做出贡献,请提出一个描述您打算添加的功能的问题,并提交一个拉取请求。
许可证
此包采用 MIT 许可证发布。
项目详情
csv_trimming-1.1.1.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 17fa6a276a6a0e9c0eadd328ecf1947e638f580515870f351d32a225026b7ab3 |
|
MD5 | 088457ce0258be47ff5b7bb13f91e06e |
|
BLAKE2b-256 | 6a3b6473544d571b9d405f7eec84c1729d6e774b02fe56a482f4e5b8409a26b5 |