python pandas
一、DataFrame
1、构造
# 从字典构建 d = {'col1:[1,2], 'col2':[3,4]} d = {'col1:[1], 'col2':[3]} df = pd.DataFrame(data=d) df = pd.DataFrame(data=d, type=np.int8 ) df.dyptes # 从包括series的字典构建 d = {'col1': [0, 1, 2, 3], 'col2': pd.Series([2, 3], index=[2, 3])} pd.DataFrame(data=d, index=[0, 1, 2, 3]) # 从numpy数组 df2 = pd.DataFrame(np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]), columns=['a', 'b', 'c']) # 从有列标签的numpy数组构建 data = np.array([(1, 2, 3), (4, 5, 6), (7, 8, 9)], dtype=[("a", "i4"), ("b", "i4"), ("c", "i4")]) df3 = pd.DataFrame(data, columns=['c', 'a']) # 从dataclass定义的数据类型构建 from dataclasses import make_dataclass Point = make_dataclass("Point", [("x", int), ("y", int)]) pd.DataFrame([Point(0, 0), Point(0, 3), Point(2, 3)])
2、访问
1).loc:通过行索引(index)和列名标签来访问,通过布尔数组访问
(1).loc['time'] 返回某行,其中time是索引中某个值,可以提前通过把某列为索引
(2).loc['r', 'c'] 返回某个值
(3)例如访问某个时间点的某列值:
df.set_index('时间') df.loc['时间', '某列名称']
2)iloc:通过位置索引来访问,也可以通过布尔数组访问
(1)访问
mydict = [{'a': 1, 'b': 2, 'c': 3, 'd': 4}, {'a': 100, 'b': 200, 'c': 300, 'd': 400}, {'a': 1000, 'b': 2000, 'c': 3000, 'd': 4000 }] df = pd.DataFrame(mydict) ## 一维 # 获取第一行,类型为Series df.loc[0] # 获取第一行,或指定几行,类型为DataFrame df.loc[[0]] df.iloc[[0, 1]] # 用切片指定范围 df.iloc[:3] # 布尔数组,掩码作用 df.iloc[[True, False, True]] df.iloc[lambda x: x.index % 2 == 0] ## 二维 # 获取某行某列值 df.iloc[0, 1] # 获取某列 df.ilo[:, 1] # 去掉第一列 df.iloc[:, 1:] # 其他切片 df.iloc[[0, 2], [1, 3]] df.iloc[1:3, 0:3] # 布尔掩码 df.iloc[:, [True, False, True, False]] df.iloc[:, lambda df: [0, 2]]
(2)迭代某列
num = len(df.index) for i in range(num): value = df['某列名称'].iloc[i]
3)iat:通过行/列对位置获取单个值 ,跟iloc类似
df = pd.DataFrame([[0, 2, 3], [0, 4, 1], [10, 20, 30]], columns=['A', 'B', 'C']) # 通过行列号 df.iat[1, 2] df.iat[1, 2] = 10 # 在series中获取值 df.loc[0].iat[1]
4)at:通过标签对获取某个值,跟loc类似
df = pd.DataFrame([[0, 2, 3], [0, 4, 1], [10, 20, 30]], index=[4, 5, 6], columns=['A', 'B', 'C']) # 通过行列标签 df.at[4, 'B'] df.at[4, 'B'] = 10
5)索引与标签结合
# 通过索引取出series,通过标签取值! code = df.loc[df['名称'] == name].iloc[0].at['代码']
4)迭代行:iteritems()
3、切片
1)去掉第一列
kData = KDJData.iloc[:, 1:]
4、转换
1)为了采样,可能需要转换成索引时间为datetime周期时间:pandas.to_datetime()
pd.index = pd.to_datetime(df.index)
...
4、采样:resample
1)采样周期为天、30分钟
(1)dropna():因为数据的时间不是周期连续的,中间很多时间没有数据,采样时,会变成NAN。参考链接
# 采样周期为天、30分钟 df_D = df.resample('D').last().dropna() df_30min = df.resample('30min, closed='right', label='right').last().dropna() # df_D = df.resample('D').agg({'open': 'first', 'high': 'max', 'low': 'min', 'close': 'last', 'volume': 'sum'}).dropna()
5、操作
# 赋值 df.loc[df['时间' > t], '时间'] = 1 # 去掉最后一行 df.drop(df.tail(n).index) #从尾部去掉 n 行 df.dorp(df.head(n).index) #从头去掉 n 行 PageDF = PageDF[:-1]
二、Series
1、构造函数
1)直接构造
# 构建一个空Series,需要指定类型 s = pd.Series([], dtype='float64') # 从字典创建 d = {'a': 1, 'b': 2, 'c': 3} ser = pd.Series(data=d, index=['a', 'b', 'c']) # 字典的关键字必须匹配Series的索引,要不然不起作用 d = {'a': 1, 'b': 2, 'c': 3} ser = pd.Series(data=d, index=['x', 'y', 'z'])
2)由于输入的数据类型不同,指定的copy=False效果也不同
# 尽管指定了copy=False,可是依然copy了
r = [1, 2] ser = pd.Series(r, copy=False) ser.iloc[0] = 999 # r #[1, 2] # ser # 0 999 # 1 2 # dtype: int64 # 未copy r = np.array([1, 2]) ser = pd.Series(r, copy=False) ser.iloc[0] = 999 # r # array([999, 2]) # ser # 0 999 # 1 2 # dtype: int64
3、遍历、判断
# 判断值是否在序列中 if 'x' in s.value: continue
4、时间处理
1)格子化时间:(30min、H等)
endDateTime = time.strftime('%Y-%m-%d %H:%M:%S') # 构造 endDateTimeIndex = pd.DatetimeIndex([endDateTime]) # 往前的30分钟 last30MinIndex = endDateTimeIndex.floor('30min') # 字符串化 last30Min = last30MinIndex[0].strftime('%Y-%m-%d %H:%M:%S')
3、转换
1)转换成列表
ls = df['列名称'].to_list()
4、操作
# 去掉NAN s.drop(inplace=True) # 获取最大、最小值所在的索引 s.idxmax() s.idxmin()
5、保存
1)保存到csv
四 其他
1、pandas中中文保存到csv乱码
df.to_csv("a.csv",encoding='utf_8_sig',index=Flase,sep=',')