我有一个超大的csv.gzip文件,有59个行。我想根据特定条件筛选某些行的文件,并将所有这些行放在新的主csv文件中。截至目前,我将gzip文件分成了118个较小的csv文件并将其保存在我的计算机上。我用以下代码做到了:
import pandas as pd
num = 0
df = pd.read_csv('google-us-data.csv.gz', header = None,
compression = 'gzip', chunksize = 500000,
names = ['a','b','c','d','e','f','g','h','i','j','k','l','m'],
error_bad_lines = False, warn_bad_lines = False)
for chunk in df:
num = num + 1
chunk.to_csv('%ggoogle us'%num ,sep='\t', encoding='utf-8'
上面的代码工作得很好,我现在有一个包含118个小文件的文件夹。然后,我编写代码逐个浏览118个文件,提取符合特定条件的行,并将它们全部附加到我已创建并命名为“google final us”的新csv文件中。这是代码:
import pandas as pd
import numpy
for i in range (1,118)
file = open('google final us.csv','a')
df = pd.read_csv('%ggoogle us'%i, error_bad_lines = False,
warn_bad_lines = False)
df_f = df.loc[(df['a']==7) & (df['b'] == 2016) & (df['c'] =='D') &
df['d'] =='US')]
file.write(df_f)
不幸的是,上面的代码给出了以下错误:
KeyError Traceback (most recent call last)
C:\Users\...\Anaconda3\lib\site-packages\pandas\indexes\base.py in
get_loc(self, key, method, tolerance)
1875 try:
-> 1876 return self._engine.get_loc(key)
1877 except KeyError:
pandas\index.pyx in pandas.index.IndexEngine.get_loc (pandas\index.c:4027)()
pandas\index.pyx in pandas.index.IndexEngine.get_loc (pandas\index.c:3891)()
pandas\hashtable.pyx in pandas.hashtable.PyObjectHashTable.get_item
(pandas\hashtable.c:12408)()
pandas\hashtable.pyx in pandas.hashtable.PyObjectHashTable.get_item
(pandas\hashtable.c:12359)()
KeyError: 'a'
During handling of the above exception, another exception occurred:
KeyError Traceback (most recent call last)
<ipython-input-9-0ace0da2fbc7> in <module>()
3 file = open('google final us.csv','a')
4 df = pd.read_csv('1google us')
----> 5 df_f = df.loc[(df['a']==7) & (df['b'] == 2016) &
(df['c'] =='D') & (df['d'] =='US')]
6 file.write(df_f)
C:\Users\...\Anaconda3\lib\site-packages\pandas\core\frame.py in
__getitem__(self, key)
1990 return self._getitem_multilevel(key)
1991 else:
-> 1992 return self._getitem_column(key)
1993
1994 def _getitem_column(self, key):
C:\Users\...\Anaconda3\lib\site-packages\pandas\core\frame.py in
_getitem_column(self, key)
1997 # get column
1998 if self.columns.is_unique:
-> 1999 return self._get_item_cache(key)
2000
2001 # duplicate columns & possible reduce dimensionality
C:\Users\...\Anaconda3\lib\site-packages\pandas\core\generic.py in
_get_item_cache(self, item)
1343 res = cache.get(item)
1344 if res is None:
-> 1345 values = self._data.get(item)
1346 res = self._box_item_values(item, values)
1347 cache[item] = res
C:\Users\...\Anaconda3\lib\site-packages\pandas\core\internals.py in
get(self, item, fastpath)
3223
3224 if not isnull(item):
-> 3225 loc = self.items.get_loc(item)
3226 else:
3227 indexer = np.arange(len(self.items))
[isnull(self.items)]
C:\Users\...\Anaconda3\lib\site-packages\pandas\indexes\base.py in
get_loc(self, key, method, tolerance)
1876 return self._engine.get_loc(key)
1877 except KeyError:
-> 1878 return
self._engine.get_loc(self._maybe_cast_indexer(key))
1879
1880 indexer = self.get_indexer([key], method=method,
tolerance=tolerance)
pandas\index.pyx in pandas.index.IndexEngine.get_loc (pandas\index.c:4027)()
pandas\index.pyx in pandas.index.IndexEngine.get_loc (pandas\index.c:3891)()
pandas\hashtable.pyx in pandas.hashtable.PyObjectHashTable.get_item
(pandas\hashtable.c:12408)()
pandas\hashtable.pyx in pandas.hashtable.PyObjectHashTable.get_item
(pandas\hashtable.c:12359)()
KeyError: 'a'
任何想法出了什么问题?我已经阅读了许多其他stackoverflow帖子(例如Create dataframes from unique value pairs by filtering across multiple columns或How can I break down a large csv file into small files based on common records by python),但仍不确定如何执行此操作。此外,如果您有比这种方法更好的方法来提取数据 - 请告诉我!
答案 0 :(得分:2)
import pandas
import glob
csvFiles = glob.glob(path + "/split files/*.csv")
list_ = []
for files in csvFiles:
df = pandas.read_csv(files, index_col=None)
df_f = df[(df['a']==7) & (df['b'] == 2016) & (df['c'] =='D') & df['d']=='US')]
list_.append(df_f)
frame = pandas.concat(list_, ignore_index=True)
frame.to_csv("Filtered Appended File")
将拆分文件夹中的所有文件保存在工作目录中......
这应该可以...通过读取目录中的所有必需文件
阅读csv会占用大量内存...所以打破它们并对它们进行处理是一种可能的解决方案......似乎你正处于正确的轨道......
答案 1 :(得分:0)
使用file.write(df_f)时,您实际上正在保存DataFrame的字符串表示形式,供人们查看。默认情况下,该表示将截断行和列,以便可以以合理的方式在屏幕上显示大帧。因此,列“a”可能会被切断。
with open('google final us.csv','a') as file:
for i in range(1, 118):
headers = i == 1
...
df_f.to_csv(file, headers=headers)
我没有测试上面的代码片段,但你应该知道如何开始。
此代码存在其他问题,您可能需要更正:
在循环之前打开要写入的文件,之后将其关闭。最好使用上下文管理器。
如果整个数据适合内存,为什么要麻烦将其拆分为118个文件?只需过滤它并使用df.to_csv()方法保存生成的DataFrame。
最后,如果这是一次性工作,为什么甚至为使用grep命令完成的事情编写代码(在类Unix系统上)?
答案 2 :(得分:0)
也许甚至没有必要将巨型CSV拆分为多个文件。您可以使用iterator
函数的chunksize
和read_csv
选项(有关更高级的用法,请参见the docs)。
file_path = 'my_big_file.csv'
chunksize = 100000
df_chunks = []
for df in pd.read_csv(file_path, chunksize=chunksize, iterator=True):
df_f = df.loc[(df['a']==7) & (df['b'] == 2016) & (df['c'] =='D') &
df['d'] =='US')]
df_chunks.append(df_f)
master_df = pd.concat(df_chunks)
还有low_memory
选项也可以传递给read_csv
:
内部对文件进行分块处理,从而降低了内存使用量 解析时,但可能是混合类型推断。确保不混 类型要么设置为False,要么使用dtype参数指定类型。 请注意,无论如何,整个文件都会读入单个DataFrame中, 使用chunksize或iterator参数以块形式返回数据。 (仅对C解析器有效)
对于整个数据集上的一些更高级的操作(例如,您需要对一些数据集进行分组),可能还值得考虑将数据输入到SQL数据库中并在那里进行操作-熊猫在SQL读/写中提供了一些支持。 here有一个很好的例子。