How to print column names that are common to all CSV files
我一起整理了一些我认为可以打印出文件夹中所有CSV文件通用的所有列名称的代码。我正在使用内部联接,但它的作用类似于外部联接。对此,必须有一个快速修复。
1 2 3 4 5 6 7 8 9 10 11 12
| import glob
import pandas as pd
files = glob.glob(r'C:\\my_files\\*.csv')
def get_merged(files, **kwargs):
df = pd.read_csv(files[0], **kwargs)
for f in files[1:]:
df = df.merge(pd.read_csv(f, **kwargs), how='inner')
return df
print(get_merged(files)) |
因此,如果我有4个文件包含以下列:
1
| cola colb colc cold cole |
我有1个包含以下列的文件:
我想看这个:
- 内部merge将基于公共索引而不是基于公共列的IIRC进行合并。因此,获得大量的列很有意义。
-
您要merge而不是join。 merge适用于列名,而join适用于索引
-
pandas对此有点矫kill过正。您愿意接受没有pandas的解决方案吗?
-
我只需要列名,然后读入所有这些数据就毫无价值。抓住标题,然后您就需要set.intersection(或Index.intersection)。
-
没有大pandas不是矫kill过正。因此,只需读入列名,而不用pd.read_csv(..., nrows=1)读入数据。或者,如果您希望使用csv读取本机Python解决方案,则可以在列名上迭代使用set()交集。
-
检查所有这些文件中的列名,并确保您实际想要的五个列名是相同的string。当您进行内部联接时,默认情况下,pandas将为您加载的每个数据框使用索引作为要匹配的列值(换句话说,索引的作用类似于数据库中的id列)。
-
如果仅读取第一行,pandas可能并不是性能过高的选择,但是如果您要从一组CSV文件中获取一组列名,则pandas仍然是一个很大的依赖项。但是,我想,如果您唯一的工具是锤子,那么所有问题都会像钉子一样。无论哪种方式,这个问题似乎都是一个骗子,因为无论有没有pandas,都有关于这个问题的答案。
-
@PauloScardine:我展示了两种方法:pandas和原生Python。pandas还可以用于处理定界符/空格,引号,编码,多行...本地csv模块非常脆弱。我的经验法则是,如果您发现自己编写的代码重复了pandas的功能。
-
...实际上只读取列名,请先执行pd.read_csv(..., nrows=0),然后接受set(df.columns)
-
我本来是想像SQL set操作那样相交。我看着合并,似乎也可以。我只想要一些易于设置和维护的东西。它不必扫描成千上万个文件,也不必快如闪电,尽管我认为它可以非常快地工作,因为它只需要从每个文件中提取第一行即可。我仍然没有解决方案。我尝试了上面提到的想法。一个挑战是我不能只处理两个文件。我正在处理两个以上的文件。
-
抱歉,这不是一个骗子(我以为OP坚持要pandas),不应该被关闭;同样奇怪的是,事实证明pd.merge(..., how='inner')仍然采用了列的并集(而不是交集);它只会删除普通行而不是列。我修改了答案。
-
我注意到有些奇怪。我敢肯定,您比我更了解这些知识。无论如何,我如何才能如上所述获得结果?所发布的建议中没有一个对我有效。
-
...并且如果正确的数据框没有所有这些共同的列,则pd.merge(left, right, on = left.columns, how='inner')会给出错误。因此,merge/join不是我们要寻找的机器人。
-
@asher:我的两个建议都起作用:我对第一个进行了编码,并对其进行了测试,并且它可以工作。如果仍然有问题,请在问题中编辑更新的代码。
-
@PauloScardine:您能删除贬低的言论吗?"但是,如果您唯一的工具是锤子,我想所有问题都像钉子一样。"如果您曾经有很多使用Unicode编码的大型CSV文件,包括引号,转义,空格,各种分隔符等,那么pandas是我知道的唯一工具,它可以立即完成工作编写大量不必要的手动CSV解析代码...我们每天在SO上已经看到太多了。是的,如果它是三个小的CSV文件,那就太过分了。取决于操作环境。
-
@smci道歉或听起来粗鲁,英语不是我的母语。如果pandas对OP所描述的任务来说是过大的杀伤力,那么请允许我们不同意。
-
这回答了你的问题了吗?两个pandas数据框中共有的列的列表
您可以使用pandas或纯Python来计算列名称的set-intersection。
1)大pandas解决方案
1 2 3 4 5 6
| def get_common_columns(files, **kwargs):
"""Get set intersection of column-names of specified CSV files"""
common_columns = set(pd.read_csv(files[0], nrows=0, **kwargs).columns)
for f in files[1:]:
common_columns &= set(pd.read_csv(f, nrows=0, **kwargs).columns)
return common_columns |
-
我测试了它并且有效
-
pandas并不过分:仅读取列名而不读取数据,只需执行pd.read_csv(..., nrows=0)然后取set(df.columns)
-
原来我们不能使用merge / join。即使merge(..., how='inner')也采用并集而不是列的交集。 FYI merge适用于列名,而join适用于索引。但是他们逐行加入
2)带有csv和set()的本机Python解决方案
-
同样的想法,只是在本机Python中
-
用csv读取列标题,然后在列名称上使用set()交集,反复:common_columns |= set(columns_from_current_csv)
- 我知道现在正在发生什么。我可能已经问过我最初的问题,这有点不对。我刚刚更新了我的问题。我想找到出现在CSV文件文件夹中所有文件中的列名。
-
什么是本地python解决方案?你能显示细节吗?假设我有4个具有以下字段名称的文件:colA colB colC colD colE。另外,我有1个文件,这些文件名为:colA colC colE colX。我希望最终结果显示如下:colA colC colE。因此,colA colC colE在所有列名称集中。
-
很抱歉在smci之前造成的混乱。在不同的CSV文件上可以正常工作。在我测试过的其他文件中肯定有一些奇怪的事情。非常感谢!!!
来自堆栈上的另一个答案:
1 2 3 4 5 6 7 8 9 10
| import csv
from glob import iglob
unique_headers = set()
for filename in iglob('*.csv'):
with open(filename, 'rb') as fin:
csvin = csv.reader(fin)
unique_headers.update(next(csvin, []))
print(unique_headers) |
如何使用Python读取CSV文件的标题列?