pandas使用

1. IO tools

pandas I/O API是一组顶级读写函数,访问方式如下:
pandas.read_csv通常返回pandas对象的。相应的writer函数是对象方法,类似于DataFrame.to_csv(). 下面是一个包含可用读写器的表。:
text_files

1.1 read_csv()

pd.read_csv(input_asc_file,skiprows=lambda x:x in range(7),encoding="gbk",engine='python',sep=' ',delimiter=None, index_col=False,header=None,skipinitialspace=True)

1.2 删除

删除DataFrame的某列或某行数据

  1. 删除某列或某行数据可以用到pandas提供的方法drop

  2. drop方法的用法:drop(labels, axis=0, level=None, inplace=False, errors=‘raise’)
    – axis为0时表示删除行,axis为1时表示删除列

  3. 常用参数如下:
    pandas使用_第1张图片

import pandas as pd

df1 = pd.DataFrame([['Snow','M',22],['Tyrion','M',32],['Sansa','F',18],['Arya','F',14]], columns=['name','gender','age'])
print(df1)

print('---------删除行或列:DataFrame.drop()--------')
# drop默认对原表不生效,如果要对原表生效,需要加参数:inplace=True

print("----删除单行----")
df2=df1.drop(labels=0)   # axis默认等于0,即按行删除,这里表示按行删除第0行
print(df2)

print("------删除多行------")
# 通过labels来控制删除行或列的个数,如果是删多行/多列,需写成labels=[1,3],不能写成labels=[1:2],用:号会报错
# 删除指定的某几行(非连续的)
df21=df1.drop(labels=[1,3],axis=0)   # axis=0 表示按行删除,删除第1行和第3行
print(df21)

# 要删除连续的多行可以用range(),删除连续的多列不能用此方法
df22=df1.drop(labels=range(1,4),axis=0)   # axis=0 表示按行删除,删除索引值是第1行至第3行的正行数据
print(df22)

print("----删除单列----")
df3=df1.drop(labels='gender',axis=1)  # axis=1 表示按列删除,删除gender列
print(df3)

print("----删除多列----")
# 删除指定的某几列
df4=df1.drop(labels=['gender',"age"],axis=1)  # axis=1 表示按列删除,删除gender、age列
print(df4)

1.MemoryError: Unable to allocate 539. MiB for an array with shape解决方法:
一、逐行读取
如果你用pd.read_csv来读文件,会一次性把数据都读到内存里来,导致内存爆掉,那么一个想法就是一行一行地读它,代码如下:

data = []
with open(path, 'r',encoding='gbk',errors='ignore') as f:
    for line in f:
        data.append(line.split(','))
data = pd.DataFrame(data[0:100])

这就是先用with open把csv的每一行读成一个字符串,然后因为csv都是靠逗号分隔符来分割每列的数据的,那么通过逗号分割就可以把这些列都分离开了,然后把每一行的list都放到一个list中,形成二维数组,再转换成DataFrame。

这个方法有一些问题,首先读进来之后索引和列名都需要重新调整,其次很多数字的类型都发生了变化,变成了字符串,最后是最后一列会把换行符包含进去,需要用replace替换掉。

不知道为什么,用了这个操作之后,还是出现了Memory error的问题。基于这些缺点以及遗留问题,考虑第二种解决方案。

二、巧用pandas中read_csv的块读取功能

pandas设计时应该是早就考虑到了这些可能存在的问题,所以在read功能中设计了块读取的功能,也就是不会一次性把所有的数据都放到内存中来,而是分块读到内存中,最后再将块合并到一起,形成一个完整的DataFrame。

f = open(path)

data = pd.read_csv(path, sep=',',engine = 'python',iterator=True)
loop = True
chunkSize = 1000
chunks = []
index=0
while loop:
    try:
        print(index)
        chunk = data.get_chunk(chunkSize)
        chunks.append(chunk)
        index+=1

    except StopIteration:
        loop = False
        print("Iteration is stopped.")
print('开始合并')
data = pd.concat(chunks, ignore_index= True)

以上代码规定用迭代器分块读取,并规定了每一块的大小,即chunkSize,这是指定每个块包含的行数。

这个方法能够保持数据的类型,也不需要自己费心思去调整列名和index,比较方便。但不幸的是,我的还是出现了这个问题,如果你的用了这种方法还是出现memory error,你可以继续往下看。
三、扩充虚拟内存

我在运行代码的过程中发现,出现memory error错误的时候,其实我的内存只用到了40+%,所以其实不太可能会出现这个错误啊,所以我查了下,发现有说是内存被限制了,考虑关掉一些可能限制内存的软件啦,扩大虚拟内存啦,这些的。

扩大虚拟内存的方法(我的系统是win8,不过应该都大同小异):
1、打开 控制面板;
2、找到 系统 这一项;
3、找到 高级系统设置 这一项;
4、点击 性能 模块的 设置 按钮;
5、选择 高级面板,在 虚拟内存 模块点击更改;
6、记得 不要 选中“自动管理所有驱动器的分页文件大小”,然后选择一个驱动器,也就是一个盘,选中自定义大小,手动输入初始大小和最大值,当然,最好不要太大,更改之后能在查看盘的使用情况,不要丢掉太多空间。
7、都设置好之后,记得点击 “设置”, 然后再确定,否则无效,最后 重启电脑 就可以了。

悲剧的是我在设置完这一步之后还是出现了内存错误,到这一步就没有问题了的朋友就可以不用看下面一种解法了,如果还是有问题,可以接下来看。
四、更新Pandas和Numpy库为64位

如果你的Python用的是32位的,那么你的pandas和Numpy也只能是32位的,那么当你的内存使用超过2G时,就会自动终止内存。发现这个错误也是因为我察觉到报内存溢出的错误的时候,我的内存明明显示只用了40+%,然后错误提示是在pandas的core中,所以查了一下,发现原来还有这么个大坑。

解决方法就是:先检查一下你的python是多少位的,在shell中输入python,查看位数,如果是32位,那么就重装Python,装一个64位的,但同时你的库也需要重新装了。不过我执行完这一步之后,问题就完美解决了!
五、如果还有内存溢出的错

以上四种方法,按顺序逐一使用,到哪一步错误消失了就可以停止啦。当然了,如果你的内存显示使用达到了99%+,那么就是内存真的不够用,不是别的问题,如果不是数据量特别大,那就是写代码的时候的习惯问题,虽然Python有垃圾回收机制,但是有时候可能来不及回收,尤其是在循环迭代这些过程中,往往会循环完毕了才来得及收拾垃圾,所以记得及时把不要的变量del掉,或者用gc这个垃圾回收库,这样内存自然就一直清清爽爽啦~

你可能感兴趣的:(学习笔记)