Pandas Series和DataFrame的基本概念
1,创建Series
1.1,通过iterable创建Series
Series接收参数是Iterable,不能是Iterator
pd.Series(Iterable)
可以多加一个index参数,index可以接收Iterator或者Iterable:
>>> pd.Series(('a', 'b'), index=iter(range(2))) 0 a 1 b dtype: object
1.2,通过字典创建Series
key是索引:
>>> pd.Series({'a':1, 'b':2}) a 1 b 2 dtype: int64
2,Series常用方法
s = pd.Series([1, 2, 3], index=list('abc'))
Series也能像字典那样遍历:
for index, value in s.items(): print(index, value, end=';') # a 1;b 2;c 3;
和字典一样,Series的in测试默认是index操作,如果想对values操作需加上values:
print('a' in s) # True print(1 in s.values) # True
获取series的values组成的列表:
print(s.tolist()) # [1, 2, 3]
3,创建DataFrame
3.1,通过iterable组成的列表创建DataFrame
[it1, it2, ..., itN],每个it是一行数据,缺省的index, columns是从0开始的int
>>> pd.DataFrame([(1, 2, 3), [4, 5, 6], range(3, 6), 'abc']) 0 1 2 0 1 2 3 1 4 5 6 2 3 4 5 3 a b c
it长度不等时会自动用NaN或者None填充:
>>> pd.DataFrame([(1, 2), [4, 5], range(3, 6), 'abc']) 0 1 2 0 1 2 None 1 4 5 None 2 3 4 5 3 a b c >>> pd.DataFrame([(1, 2, 3), [4, 5, 6], range(3, 6), 'ab']) 0 1 2 0 1 2 3.0 1 4 5 6.0 2 3 4 5.0 3 a b NaN
指定index和columns:
>>> pd.DataFrame([(1, 2, 3), [4, 5, 6], range(3, 6), 'abc'], index=range(4), columns=list('ABC')) A B C 1 1 2 3 2 4 5 6 3 3 4 5 4 a b c
3.2,通过numpy矩阵创建DataFrame
np_data = np.random.random((3, 4)) np_data = np.arange(12).reshape(3, 4) np_data = np.ones((3, 4)) df = pd.DataFrame(np_data)
3.3,通过“一键多值”创建DataFrame
创建dataframe,键是列名:
>>> pd.DataFrame({'a':[1, 2, 3], 'b': [4, 5, 6]}) a b 0 1 4 1 2 5 2 3 6
可以设置index:
>>> pd.DataFrame({'a':[1, 2, 3], 'b': [4, 5, 6]}, index=list('456')) a b 4 1 4 5 2 5 6 3 6
创建df时更改columns会出问题:
>>> pd.DataFrame({'a':[1, 2, 3], 'b': [4, 5, 6]}, columns=list('AB')) Empty DataFrame Columns: [A, B] Index: []
这种创建方法可以看做是按列创建df,需要事先建很多列表,最后一次性赋给df
3.4,通过“字典列表”创建DataFrame
pd.DataFrame([{'a':1 , 'b': 4}, {'a':2 , 'b': 5}, {'a':3 , 'b': 6}]) a b 0 1 4 1 2 5 2 3 6
这种方法只需要创建一个列表,然后不停往该列表里添加字典即可,推荐!
3.5,df.loc,df.iloc,df.ix等逐行/逐单元格创建DataFrame
事先创建好dataframe,然后用dfdf.loc,df.iloc,df.ix逐行逐单元格增加数据,例如:
df = pd.DataFrame() for index, item in enumerate(zip('abcde', range(5))): df.loc[index, 'A'] = item[0] df.loc[index, 'B'] = item[1]
效率非常低,不推荐
4,SettingWithCopyWarning
对DataFrame的弱引用对象进行拷贝进行赋值会触发SettingWithCopyWarning。
通过bool序列筛选拿到的是dataframe的弱引用对象。对弱引用对象进行修改时,不会影响到原来的dataframe。
>>>df = pd.DataFrame(np.arange(16).reshape(4, 4), columns=list('ABCD')) >>>df1 = df[df['B'] > 2] >>>df1.is_copy <weakref at 0x08B5F6C0; to 'DataFrame' at 0x00CC5070> >>>df1['A'] = 0 SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead >>>df1 # df1会改变 A B C D 1 0 5 6 7 2 0 9 10 11 3 0 13 14 15 >>>df # df不会改变 A B C D 0 0 1 2 3 1 4 5 6 7 2 8 9 10 11 3 12 13 14 15
df1是df的弱引用拷贝,对df1进行赋值会触发SettingWithCopyWarning。
如果df1 = df.copy()不会触发该警告。
另外,如果是获取一个列,则拿到的是视图,并不是弱引用,对该视图进行的修改会反映到源dataframe:
>>>df = pd.DataFrame(np.arange(12).reshape(3, 4), columns=list('ABCD')) >>>a = df['A'] >>>a.loc[1] = 55 >>>a A B C D 0 0 1 2 3 1 55 5 6 7 2 8 9 10 11