0%

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
import pandas as pd
import numpy as np
import os,re,random,csv,shutil
from datetime import date,time,timedelta
from pyecharts.charts import Kline, Line, Bar, Grid,Map,Pie,Timeline,Geo
from pyecharts.commons.utils import JsCode
from pyecharts import options as opts
from pyecharts.globals import CurrentConfig, NotebookType,ThemeType,ChartType, SymbolType
from pytdx.reader import TdxDailyBarReader, TdxFileNotFoundException
import baostock as bs
from chinese_calendar import is_workday, is_holiday

reader = TdxDailyBarReader()

def getfullcode(code):
if code.startswith('6',0,1):
code = 'sh' + code
elif code.startswith('0',0,1) or code.startswith('3',0,1):
code = 'sz' + code
return code


def get_filepath(code):
"""
根据6位数字的股票代码获取完整的日k线数据路径
"""
code = getfullcode(code)
fd1 = r'D:\new_tdx\vipdoc'
fd2 = f"{re.match(r'[a-z]+',code).group()}\lday\{code}.day"
return os.path.join(fd1,fd2)

def get_nameidu(code):
"""
根据股票代码获取对应的股票名称和所属行业
返回list [name,idu]
code: '600000' str格式
"""
dn = pd.read_csv(r"D:\stock_data\allstock.csv",dtype={'代码':str})
dn['代码'] = dn['代码'].map(lambda x: x.rjust(6,'0'))
names = dict(zip(dn['代码'].tolist(),dn['名称'].tolist()))
idus = dict(zip(dn['代码'].tolist(),dn['细分行业'].tolist()))
return [names.get(code),idus.get(code)]

def add_ma(data):
'''添加列数据,均线数据'''
data['ma5'] = data['close'].rolling(5).mean()
data['ma10'] = data['close'].rolling(10).mean()
data['ma20'] = data['close'].rolling(20).mean()
data['ma30'] = data['close'].rolling(30).mean()
data['ma60'] = data['close'].rolling(60).mean()
data['ma90'] = data['close'].rolling(90).mean()
data['ma120'] = data['close'].rolling(120).mean()
data['ma250'] = data['close'].rolling(250).mean()
data.dropna(inplace=True)
data = data.applymap(lambda x: round(x,2) if isinstance(x,float) else x)
return data


def get_tdxklinedata(code):
"""
根据股票代码,读取行情数据。为DF添加均线数据列,并对数值取小数点2位数。
"""
df = reader.get_df(get_filepath(getfullcode(code)))
return add_ma(df)


def pelevel(arr):
"""
计算arr中最后一个数在数组的分位点
返回: value ---float
参数:
arr: numpy的一维数组
"""
target = arr[-1]
level = 1 - np.count_nonzero(target <= arr) / arr.size
return level

def get_pestartdate():
x= 1050
dates = pd.date_range(end=date.today(),periods=x,freq='B')
tradedates = [i for i in dates if is_workday(i)]
while len(tradedates)<1000:
x+=1
dates = pd.date_range(end=date.today(),periods=x,freq='B')
tradedates = [i for i in dates if is_workday(i)]
return [f"{tradedates[0]:%Y-%d-%d}",f"{tradedates[-1]:%Y-%m-%d}"]

pedates = get_pestartdate()
selfdate = pedates[0]
idudate = pedates[1]

def get_selfpes(code):
bs.login()
if code.startswith('6'):
code = 'sh.' + code
else:
code = 'sz.' + code
data = bs.query_history_k_data_plus(
code=code,
fields="date,code,turn,peTTM",
frequency="d",
start_date= selfdate,
adjustflag="2").get_data()
bs.logout()
truns = [round(float(i),2) for i in data['turn'].tolist()[-5:]]
pes = [f"{float(i):.2f}" for i in data['peTTM'].tolist() if i!='']
return [truns,pes]

def get_iduavgpe(code):
bs.login()
# 根据代码获得所属细分行业
idu = get_nameidu(code)[1]
# 列出该股票所属行业的全部股票代码
df_idu = pd.read_csv(r"D:\stock_data\allstock.csv",dtype={'代码':str})
codes = df_idu.query('细分行业 == @idu')['代码'].tolist()
dfpes = pd.DataFrame()
for code in codes:
if code.startswith('6'):
code = 'sh.' + code
else:
code = 'sz.' + code
data = bs.query_history_k_data_plus(
code=code,
fields="date,code,peTTM",
frequency="d",
start_date= idudate,
adjustflag="2").get_data()
dfpes = pd.concat([dfpes,data])
dfpes['peTTM'] = dfpes['peTTM'].astype(float)
bs.logout()
return dfpes['peTTM'].mean(skipna = True)


def kline(code):
"""
绘制K线图
参数: df (DataFrame)
df 必须包含 columns:['open','close','high','low','amount','date']
返回: K线图html
参数:
code: 股票代码 '60000'
"""
# df = get_tdxklinedata(code)
df = add_ma(get_tdxklinedata(code))
# K线图 x 轴数据
x_data = list(map(lambda x: x.strftime("%Y-%m-%d"), df.index.tolist()))
# k线图 y 轴数据
y_data = df[["open", "close", "low","high"]].values.tolist()
# 根据股票代码获取对应的名称和行业
name = get_nameidu(code)[0]
idu = get_nameidu(code)[1]
# 从baostock下载 pe 和 trun
trunpes = get_selfpes(code)
pe = trunpes[1][-1]
pes = np.array(trunpes[1])
# peTTM = df['peTTM'].tolist()[-1]
# 获取最近5日的换手率数据
turns = trunpes[0]
# 从k线数据表获取股票250日、500日、以及全部值并计算当前值所处的分位点
pes_250 = pes[-250:]
pes_500 = pes[-500:]
pes_750 = pes[-750:]
pes_1000 = pes[-1000:]
level1 = f"{pelevel(pes_250):.3f}"
level2 = f"{pelevel(pes_500):.3f}"
level3 = f"{pelevel(pes_750):.3f}"
level4 = f"{pelevel(pes_1000):.3f}"
# 获取股票所属行业的所有股票的pe,并计算行业pe均值
idupeavg = get_iduavgpe(code)
#-------------设置kline-------------------
k = (Kline(init_opts=opts.InitOpts(width="100%", height="1200px"))
.add_xaxis(x_data)
.add_yaxis("kline",y_data).set_global_opts(
datazoom_opts=[
opts.DataZoomOpts(type_="inside",
range_start=95,
range_end=100),
opts.DataZoomOpts(type_="slider",
xaxis_index=[0,1],
range_start=int(100 - 150/len(df)*100),
range_end=100,
is_show=True),
],
title_opts=opts.TitleOpts(
# title="K线图",
subtitle=f"代码: {code} 名称: {name} 行业: {idu} \n\n当前pe: {pe} 行业pe: {idupeavg:.2f}\n\n近5天换手率: {turns}\n\npe分位点:\n\n {level1} / 250 days\n\n {level2} / 500 days\n\n {level3} / 750 days\n\n {level4} / 1000 days ",
pos_top = '1%',
pos_right ="10%",
),
# toolbox_opts=opts.ToolboxOpts(),

)
)
# -----------------均线 折线图---------------
l =(Line(init_opts=opts.InitOpts(width="100%", height="1200px")).add_xaxis(x_data)
.add_yaxis("ma5",
df['ma5'].values.tolist(),
symbol = None,
is_symbol_show=False,
label_opts=opts.LabelOpts(is_show=False),
markpoint_opts=opts.MarkPointOpts(data=[
{"yAxis": 150}, # 增加自定义标记线
opts.MarkPointItem(type_="min"),
opts.MarkPointItem(type_="max"),
opts.MarkPointItem(type_="average")])
)
.add_yaxis("ma10",
df['ma10'].values.tolist(),
is_symbol_show=False,
label_opts=opts.LabelOpts(is_show=False),
)
.add_yaxis("ma20",
df['ma20'].values.tolist(),
is_symbol_show=False,
label_opts=opts.LabelOpts(is_show=False),
)
.add_yaxis("ma30",
df['ma30'].values.tolist(),
is_symbol_show=False,
label_opts=opts.LabelOpts(is_show=False),
)
.add_yaxis("ma60",
df['ma60'].values.tolist(),
is_symbol_show=False,
label_opts=opts.LabelOpts(is_show=False),
)
# .add_yaxis("ma90",
# df['ma90'].values.tolist(),
# is_symbol_show=False,
# label_opts=opts.LabelOpts(is_show=False),
# )
.add_yaxis("ma120",
df['ma120'].values.tolist(),
is_symbol_show=False,
label_opts=opts.LabelOpts(is_show=False),
)
.add_yaxis("ma250",
df['ma250'].values.tolist(),
is_symbol_show=False,
label_opts=opts.LabelOpts(is_show=False),
)
)

v = (Bar()
.add_xaxis(xaxis_data=date).add_yaxis(
series_name="成交额",
y_axis=df["amount"].tolist(),
xaxis_index=1,
yaxis_index=1,
label_opts=opts.LabelOpts(is_show=False),
itemstyle_opts=opts.ItemStyleOpts(color=JsCode("""
function(params) {
var colorList;
if (barData[params.dataIndex][1] > barData[params.dataIndex][0]) {
colorList = '#ef232a';
} else {
colorList = '#14b143';
}
return colorList;
}
""")),
)
.set_global_opts(
xaxis_opts=opts.AxisOpts(
type_="category",
grid_index=1,
axislabel_opts=opts.LabelOpts(is_show=False),
),
legend_opts=opts.LegendOpts(is_show=False),
))

# ---------------------叠加图表----------------------
ov1 = k.overlap(l)
ov1.render_notebook()
ov1.render('3.html')
# --------------------组合图表---------------------------
ov = k.overlap(l)
g = (Grid(init_opts=opts.InitOpts(
width="100%",
height="800px",
animation_opts=opts.AnimationOpts(animation=False),
)
)
.add_js_funcs("var barData={}".format(df[["open", "close"]].values.tolist()))
.add(ov,
grid_opts=opts.GridOpts(
pos_top="2%",
height="70%",
),
)
.add(v,
grid_opts=opts.GridOpts(
pos_top="76%",
height="19%",
),)
)
outph = f'C:\\Users\\xiaoyx\\Desktop\\{date.today():%y%m%d}'
filename = f"{code}.html"
outfile = os.path.join(outph,filename)
if os.path.exists(outph):
pass
else:
os.makedirs(outph)
return g.render(outfile)
# return g.render_notebook()


if __name__ == '__main__':
kline('000409')

Awesome-pyecharts

1
import numpy as np

np.random.rand() 均匀分布

返回一个或一组服从“0~1”均匀分布的随机样本值。随机样本取值范围是[0,1),不包括1

语法:numpy.random.rand(d0,d1,…,dn)

  • rand函数根据给定维度生成[0,1)之间的数据,包含0,不包含1,
  • dn表格每个维度
  • 返回值为指定维度的array
1
np.random.rand()
0.590981296371817
1
np.random.rand(2,3)
array([[0.56714467, 0.63703995, 0.49941825],
       [0.38784079, 0.99935756, 0.66107952]])
1
np.random.rand(2,3,2)
array([[[0.70563167, 0.15160447],
        [0.89421227, 0.15558841],
        [0.54421821, 0.74809854]],

       [[0.6801572 , 0.73294346],
        [0.5165121 , 0.41113331],
        [0.35180961, 0.89124573]]])

np.random.randn() 正态分布

返回一个或一组服从标准正态分布的随机样本值。
标准正态分布是以0为均数、以1为标准差的正态分布,记为N(0,1)

语法: numpy.random.randn(d0,d1,…,dn)

  • randn函数返回一个或一组样本,具有标准正态分布。
  • dn表格每个维度
  • 返回值为指定维度的array
1
np.random.randn()
-1.2663606042268423
1
np.random.randn(3,2)
array([[-0.62827097,  0.29785748],
       [-0.37728649, -0.32416302],
       [ 0.84430754,  0.90935055]])

np.random.randint()

语法:np.random.randint(low[,high,size,dtype])
参数:

  • low:最小值
  • hith:最大值,不包含最大值.high没有填写时,默认生成随机数的范围是[0,low)
  • size:数据个数
  • dtype:数据类型 默认np.int
1
np.random.randint(2)
0
1
np.random.randint(1,3)
2
1
np.random.randint(1,5,2)
array([4, 4])
1
np.random.randint(1,9,5)
array([8, 8, 5, 4, 5])

np.random.sample()

语法:np.random.sample(size) 在[0-1]之间产生随机数

参数:

  • size: 随机数的维度 list形式
1
np.random.sample([3,])
array([0.53148489, 0.68699926, 0.10226921])
1
np.random.sample([3,2])
array([[0.13305405, 0.14498214],
       [0.51758694, 0.93313971],
       [0.20195698, 0.83993463]])
1
2
3
4
a = [i for i in range(100,150,10)]
a

np.random.choice(a,2)
[100, 110, 120, 130, 140]

array([140, 140])
1
2
3
4
a = [i for i in range(100,150,10)]
a

np.random.choice(a,[2,3])
[100, 110, 120, 130, 140]

array([[140, 130, 120],
       [120, 120, 120]])

np.random.choice()

语法:numpy.random.choice(a, size=None, replace=True, p=None)
参数:

  • 从给定的一维数组中生成随机数
  • a为一维数组类似数据或整数;
  • size为数组维度;
  • p为数组中的数据出现的概率;长度与参数a的长度需要一致;p里的数据之和应为1
  • a为整数时,对应的一维数组为np.arange(a)
1
2
3
a = [i for i in range(100,150,10)]

np.random.choice(a,3)
1
2
3
a = [i for i in range(100,150,10)]

np.random.choice(a,[2,3])
array([[140, 130, 120],
       [120, 100, 100],
       [100, 120, 140]])
1
2
3
a = [i for i in range(100,150,10)]

np.random.choice(a,[2,3],[0.2,0.1,0.3,0.1,0.3])
array([[140, 130, 140],
       [130, 120, 140]])

numpy.random.seed()

语法:np.random.seed(a=None,version=2)
作用:使得随机数据可预测。没有返回值。称为随机数种子。不设置随机数种子,你每次随机抽样得到的数据都是不一样的。设置了随机数种子,能够确保每次抽样的结果一样。而random.seed()括号里的数字,相当于一把钥匙,对应一扇门,同样的数值能够使得抽样的结果一致。
参数:

  • a :生成随机数的种子,可以设置为一个整数(int)
1
2
np.random.seed(0)
np.random.rand(5)
array([0.5488135 , 0.71518937, 0.60276338, 0.54488318, 0.4236548 ])
1
2
np.random.seed(12345)
np.random.rand(5)
array([0.92961609, 0.31637555, 0.18391881, 0.20456028, 0.56772503])
1
2
np.random.seed(12345)
np.random.rand(5)
array([0.92961609, 0.31637555, 0.18391881, 0.20456028, 0.56772503])

Random模块

random模块常用函数
函数名 功能
random.random() 生成一个[0,1)的实数。
random.randint(a,b) 生成一个[a,b]的数字,包含a和b。
random.randrange(a,b) 生成一个[a,b)的数字,包含a,不包含b。
random.shuffle(x) 把序列x打乱。
random.choice(x) 从x中返回一个随机项,x需要是一个可变序列。
random.uniform(a,b) 生成一个a,b之间的浮点数,区间可以是浮点数。

生成一个0-1的随机浮点数

1
2
3
4
import random
import numpy as np

random.random()
0.8204615832898717

生成一个[a,b]之间的数字,包含a和b

1
random.randint(-3, 5)
-3

生成一个[a,b]的数字,包含a不包含b

1
random.randrange(-3, 5)
4

将一个序列进行重新排序,打乱序列

1
2
3
a = list("ABCDE")
random.shuffle(a)
a
['E', 'D', 'A', 'B', 'C']

返回一个序列中的一个随机元素

语法:random.choice(seq)

从非空序列中随机选取一个数据并返回

  • seq:可以是list、tuple、str、set。
1
2
3
random.choice([-3, 3, 5])

random.choice([str(i).rjust(3,"0") for i in range(1000)])
3

'265'

返回一个序列中的多个元素

语法:random.choices(seq,weights=None,*,cum_weights=None,k=1)

  • seq:集群。
  • weights:相对权重
  • cum_weights:累加权重。
  • k:选取次数。

作用:从集群中随机选取k次数据,返回一个列表,可以设置权重。
注意:每次选取都不会影响原序列,每一次选取都是基于原序列。

1
2
3
a = [i for i in range(100,150,10)]
a
random.choices(a,k=5)
[100, 110, 120, 130, 140]

[120, 100, 100, 110, 100]
1
2
3
4
5
6
7
8
9
10
# 配置权重参数,参数形式是一个与之对应数量的seq,而且权重数字与元素一一对应
# 此处设置了的权重为:[1,2,3,0,2], 相当于{100:1,110:2,120:3,130:0,140:2}
# 130 的权重是0 ,那么永远也选不到。
# 100的概率:1/(1+2+3+0+2) = 1/8
# 110的概率:2/(1+2+3+0+2) = 2/8
# 120的概率:3/(1+2+3+0+2) = 3/8
# 130的概率:0/(1+2+3+0+2) = 0
# 140的概率:2/(1+2+3+0+2) = 2/8

random.choices(a,weights=[1,2,3,0,2],k=10)
[140, 140, 120, 120, 110, 140, 110, 120, 120, 110]
1
2
3
4
# cum_weights 累加权重,设置方法与相对权重一致
# 若:cum_weights=[1,2,3,4,5] 第一个元素的权重是1,第二个元素的权重为2-1,第三个:3-2,第四个:4-3

random.choices(a,cum_weights=[1,3,6,10,11],k=5)
[110, 130, 120, 110, 130]

用于生成指定范围内的随机浮点数

1
round(random.uniform(-3, 6), 2)
-1.69

Eval()函数

返回传入字符串的表达式的结果。就是说:将字符串当成有效的表达式 来求值 并 返回计算结果。

eval函数就是实现list、dict、tuple与str之间的转化,同样str函数把list,dict,tuple转为为字符串

eval的语法

  • eval(expression[, globals[, locals]])
  • expression : 表达式。
  • globals : (可选参数)变量作用域,全局命名空间,如果被提供,则必须是一个字典对象。
  • locals : (可选参数)变量作用域,局部命名空间,如果被提供,可以是任何映射对象。

eval有两个可选参数是命名空间,那么什么是命名空间?

命名空间

  • 名称到对象的映射。、
  • python是用命名空间来记录变量的轨迹的,命名空间是一个dictionary,键是变量名,值是变量值。
  • 各个命名空间是独立没有关系的,一个命名空间中不能有重名,但是不同的命名空间可以重名而没有任何影响

命名空间分类

  • python程序执行期间会有2个或3个活动的命名空间(函数调用时有3个,函数调用结束后2个)。、
  • 按照变量定义的位置,可以划分为以下3类:
    1. Local:局部命名空间,每个函数所拥有的命名空间,记录了函数中定义的所有变量,包括函数的入参、内部定义的局部变量。
    2. Global:全局命名空间,每个模块加载执行时创建的,记录了模块中定义的变量,包括模块中定义的函数、类、其他导入的模块、模块级的变量与常量。
    3. Built-in,python自带的内建命名空间,任何模块均可以访问,放着内置的函数和异常。

命名空间的生命周期

  1. Local在函数被调用时才被创建,但函数返回结果或抛出异常时被删除。(每一个递归函数都拥有自己的命名空间)。
  2. Global在模块被加载时创建,通常一直保留直到python解释器退出。
  3. Built-in在python解释器启动时创建,一直保留直到解释器退出。

命名空间创建顺序

  • python解释器启动 –>创建内建命名空间 –> 加载模块 –> 创建全局命名空间 –>函数被调用 ->创建局部命名空间

命名空间销毁顺序

  • 函数调用结束 -> 销毁函数对应的局部命名空间 -> python虚拟机(解释器)退出 ->销毁全局命名空间 ->销毁内建命名空间

python解释器加载阶段会创建出内建命名空间、模块的全局命名空间,局部命名空间是在运行阶段函数被调用时动态创建出来的,函数调用结束会动态销毁的。

全局命名空间存储在一个叫globals()的dict对象中;print (globals())来查看该函数体内的所有变量名和变量值

局部命名空间存储在一个叫locals()的dict对象中。用print (locals())来查看该函数体内的所有变量名和变量值

1
2
3
4
import numpy as np
import pandas as pd
import os,re,random
from datetime import date,time
1
2
locals()

1
globals()

函数的参数

当后两个参数都为空时,很好理解,就是一个string类型的算术表达式,计算出结果即可。等价于eval(expression)。

当locals参数为空,globals参数不为空时,先查找globals参数中是否存在变量,并计算。

当两个参数都不为空时,先查找locals参数,再查找globals参数。

1
2
3
# 无参数:
a = "(1+2)**3"
eval(a)
27
1
2
3
4
# 字符串中包含变量:
a = (1 + 2) ** 3
b = 2**4
eval("a + b")
43
1
2
3
4
# 
c = "(1+2)**3"
d = "2**4"
eval("c + ' ' + d")
'(1+2)**3 2**4'
1
2
3
4
# 字符串转成字典或者列表
eval("[1,3,'a',50,'python']")

eval("{'name':'john','age':'18'}")
[1, 3, 'a', 50, 'python']


{'name': 'john', 'age': '18'}
1
2
3
4
5
6
# 传递全局变量
# 当存在相同的全局变量时,保留最后一个出现的

eval("{'name':'john','age':age}", {"age": 18})

eval("{'name':'john','age':age}", {"age": 18}, {"age": 28})
{'name': 'john', 'age': 18}


{'name': 'john', 'age': 28}
1
2
3
4
# 传递本地变量
# 既有global和local时,变量值先从local中查找
age = 28
eval("{'name':'john','age':age}", {"age": 18}, locals())
{'name': 'john', 'age': 28}
1
2
3
4
5
lst = [i for i in range(20) if i%3==0 and i >0]
lst

eval("lst[3]")
eval("{k:v for v ,k in enumerate(lst)}")
[3, 6, 9, 12, 15, 18]

12

{3: 0, 6: 1, 9: 2, 12: 3, 15: 4, 18: 5}
1
eval('input()')
'1+2*3'
1
2
s = input()
eval(s)
7
1
2
3
4
a = '1 + 2 + 3'
eval(a)

eval('1+2+3')
6

6
1
eval("[i for i in os.listdir() if re.search(r'^\w{3}\.ipynb$',i)]")
['字符串.ipynb', '字符画.ipynb', '解析式.ipynb', '运算符.ipynb']

DataFrame.eval

  • df 有eval
  • 但是其他数据集不可以。list,set,dict,Series
1
2
3
4
5
a = 'np.random.randint(50,100,5)'
eval(a)
dct = {'a':eval(a),'b':eval(a),'c':eval(a),'d':eval(a),'e':eval(a),}
df = pd.DataFrame(dct)
df
array([56, 82, 83, 58, 66])
a b c d e
0 63 96 52 74 93
1 62 53 86 92 62
2 60 75 54 79 88
3 98 66 67 85 68
4 90 87 53 94 54
1
df.eval('a>80')
0    False
1    False
2    False
3     True
4     True
Name: a, dtype: bool
1
df[df.eval('a > 80')]
a b c d e
3 98 66 67 85 68
4 90 87 53 94 54

1
2
3
4
import numpy as np
import pandas as pd
import re,os,random
from datetime import date,time,timedelta,datetime

str.isdigit()

  • 如果字符串只包含数字则返回 True 否则返回 False。
1
2
3
4
a = ''
c = '37'

a.isdigit()
False
1
c.isdigit()
True

str.isnumeric()

  • 如果字符串中只包含数字字符,则返回 True,否则返回 False
1
2
3
a = '18'

a.isnumeric()
True
1
''.isnumeric()
False

str.isspace()

  • 如果字符串中只包含空格,则返回 True,否则返回 False.
1
2
3
''.isspace()

' '.isspace()
False

True

str.isalnum()

  • 如果 string 至少有一个字符并且所有字符都是字母或数字则返回 True,否则返回 False
1
2
3
4
# 至少有 1 个字母或数字;没有字母和数字之外的符号
'abc'.isalnum()
'123'.isalnum()
'a2b3ccc'.isalnum()
True

True

True
1
2
3
# 有空格
' a2b3ccc'.isalnum()
'a 2b3ccc'.isalnum()
False

False

.isidentifier()

  • 字符串是有效标识符,则 isidentifier() 方法返回 True,否则返回 False
  • 如果字符串仅包含字母数字字母(a-z)和(0-9)或下划线(_),则该字符串被视为有效标识符。有效的标识符不能以数字开头或包含任何空格。
1
2
3
# 字母和数字以及 `_`组成,且非数字开头
'abc345'.isidentifier()
'abc_345'.isidentifier()
True

True
1
2
# 包含有除 `_` 之外的其他符号
'abc_|345'.isidentifier()
False
1
2
# 包含有空格
'abc_ 345'.isidentifier()
False
1
2
# 数字开头
'1abc_ 345'.isidentifier()
False

set.issubset(sequence)

  • 如果集合中的所有项目都存在于指定集合中,则 issubset() 方法将返回 True,否则返回 False。
  • set: {}
  • sequence: 序列
1
2
3
4
5
6
7
8
# 数据集 set 是否包为 序列的子集
# set 是否被 seq 包含
a = {1,2,4}
b = [1,2,3,4]
c = [1,2,3]

a.issubset(b)
a.issubset(c)
True

False

判断是否为空

  1. df.empty
  2. not seq
1
2
3
# DataFrame.empty
df = pd.DataFrame()
df.empty
True
1
2
3
4
5
6
7
8
# seq 是否为空。 not seq
lst = []
st = {}
dct = {}

not lst
not st
not dct
True

True

True

type() / isinstance()

  1. type()
  2. isinstance(obj,type)
1
2
3
4
5
6
# type str,int,float,Nan,
type('')
type(' ')
type(np.nan)
type('abc')
type(123)
str

str

float

str

int
1
2
3
# type() seq
type([])
type({})
list

dict
1
2
3
# type() df,sr
type(pd.DataFrame())
type(pd.Series())
pandas.core.frame.DataFrame

pandas.core.series.Series
1
2
# datetime
type(date.today())
datetime.date
1
2
3
4
5
# str,int,float,Nan
isinstance('a',str)
isinstance(1,int)
isinstance(1,float)
isinstance(np.nan,float)
True

True

False

True
1
2
3
4
# seq
isinstance(['a'],list)
isinstance({'a'},set)
isinstance({'a':45},dict)
True

True

True
1
2
3
# df,sr
isinstance(pd.Series(),pd.core.series.Series)

True
1
2
3
4
5
6
# 类型可以指定多个。判断一个值或集合是否为多个类型
isinstance(123,float|int)

a = np.pi
isinstance(a,float|int)
type(a)
True

True

float

1
2
3
import numpy as np
import pandas as pd
import re,os,random
1
2
3
4
5
dct = {'name':['Python','Java','C++','Sql','Html','Css'],
'score':[90,30,np.nan,np.nan,78,np.nan],'pop':[65,43,np.nan,88,np.nan,90]}

df = pd.DataFrame(dct)
df
name score pop
0 Python 90.0 65.0
1 Java 30.0 43.0
2 C++ NaN NaN
3 Sql NaN 88.0
4 Html 78.0 NaN
5 Css NaN 90.0

检查缺失值

  1. isnull()
  2. isna
1
2
3
df.isnull().sum()

df.isna().sum()
name     0
score    3
pop      2
dtype: int64






name     0
score    3
pop      2
dtype: int64

处理缺失值

平均值填充缺失值

  1. fillna(Series.mean())
  2. fillna(Series.interpolate())
1
2
3
4
# 填充缺失值:该列的平均值
df['score'] = df['score'].fillna(df['score'].mean())
df

name score pop
0 Python 90.0 65.0
1 Java 30.0 43.0
2 C++ 66.0 65.5
3 Sql 66.0 88.0
4 Html 78.0 89.0
5 Css 66.0 90.0
1
2
3
4
5
6
7
8
9
10
11
12
dct = {'name':['Python','Java','C++','Sql','Html','Css'],
'score':[90,30,np.nan,np.nan,78,np.nan],'pop':[65,43,np.nan,88,np.nan,90]}

df = pd.DataFrame(dct)
df

# 填充缺失值:缺失值上下的数字平均值。
df['score'] = df['score'].fillna(df['score'].interpolate())
# df

df['pop'] = df['pop'].fillna(df['pop'].interpolate())
df
name score pop
0 Python 90.0 65.0
1 Java 30.0 43.0
2 C++ NaN NaN
3 Sql NaN 88.0
4 Html 78.0 NaN
5 Css NaN 90.0
name score pop
0 Python 90.0 65.0
1 Java 30.0 43.0
2 C++ 46.0 65.5
3 Sql 62.0 88.0
4 Html 78.0 89.0
5 Css 78.0 90.0

缺失值前后的值填充

  1. fillna(axis=0/1,method = ‘ffill/bfill/pad’)
  2. axis : 0: 纵向, 1:横向
  3. method: ffill: 填充前值,bfill:填充后值,pad:优先取前值,否则取后值
1
2
3
4
5
6
7
8
dct = {'name':['Python','Java','C++','Sql','Html','Css'],
'score':[90,30,np.nan,np.nan,78,np.nan],'pop':[65,43,np.nan,88,np.nan,90]}

df = pd.DataFrame(dct)
df

df.fillna(axis=0,method='ffill')

name score pop
0 Python 90.0 65.0
1 Java 30.0 43.0
2 C++ NaN NaN
3 Sql NaN 88.0
4 Html 78.0 NaN
5 Css NaN 90.0
name score pop
0 Python 90.0 65.0
1 Java 30.0 43.0
2 C++ 30.0 43.0
3 Sql 30.0 88.0
4 Html 78.0 88.0
5 Css 78.0 90.0
1
2
3
4
5
6
7
dct = {'name':['Python','Java','C++','Sql','Html','Css'],
'score':[90,30,np.nan,np.nan,78,np.nan],'pop':[65,43,np.nan,88,np.nan,90]}

df = pd.DataFrame(dct)
df

df.fillna(axis=0,method='bfill')
name score pop
0 Python 90.0 65.0
1 Java 30.0 43.0
2 C++ NaN NaN
3 Sql NaN 88.0
4 Html 78.0 NaN
5 Css NaN 90.0
name score pop
0 Python 90.0 65.0
1 Java 30.0 43.0
2 C++ 78.0 88.0
3 Sql 78.0 88.0
4 Html 78.0 90.0
5 Css NaN 90.0
1
2
3
4
5
6
7
dct = {'name':['Python','Java','C++','Sql','Html','Css'],
'score':[90,30,np.nan,np.nan,78,np.nan],'pop':[65,43,np.nan,88,np.nan,90]}

df = pd.DataFrame(dct)
df

df.fillna(axis=0,method='pad')
name score pop
0 Python 90.0 65.0
1 Java 30.0 43.0
2 C++ NaN NaN
3 Sql NaN 88.0
4 Html 78.0 NaN
5 Css NaN 90.0
name score pop
0 Python 90.0 65.0
1 Java 30.0 43.0
2 C++ 30.0 43.0
3 Sql 30.0 88.0
4 Html 78.0 88.0
5 Css 78.0 90.0

删除缺失值

  1. df.dropna(axis,how,threst,subset,inplace)
  2. axis:0为行 1为列,default 0,数据删除维度
  3. how:{‘any’, ‘all’}, default ‘any’,any:删除带有nan的行;all:删除全为nan的行
  4. threst:int,保留至少 int 个非nan行
  5. subset:list,在特定列缺失值处理
  6. inplace:bool,是否修改源文件
1
2
3
4
5
6
7
8
9
10
11
dct = {'name':['Python','Java','C++','Sql','Html','Css'],
'score':[90,30,np.nan,np.nan,78,np.nan],'pop':[65,43,np.nan,88,np.nan,90]}

df = pd.DataFrame(dct)
df

# 删除缺失值所在的行
df.dropna(axis=0)

# 删除缺失值所在的列
df.dropna(axis=1)
name score pop
0 Python 90.0 65.0
1 Java 30.0 43.0
2 C++ NaN NaN
3 Sql NaN 88.0
4 Html 78.0 NaN
5 Css NaN 90.0
name score pop
0 Python 90.0 65.0
1 Java 30.0 43.0
name
0 Python
1 Java
2 C++
3 Sql
4 Html
5 Css
1
2
3
4
5
# thresh 和 how 不能同时使用
df.dropna(axis=0,
# how='any',
thresh=2,
)
name score pop
0 Python 90.0 65.0
1 Java 30.0 43.0
3 Sql NaN 88.0
4 Html 78.0 NaN
5 Css NaN 90.0
1
2
3
4
df.dropna(axis=0,
how='any',
subset=['score'],
)
name score pop
0 Python 90.0 65.0
1 Java 30.0 43.0
4 Html 78.0 NaN

na_action

  1. 主要应用在 map函数下
  2. None:默认值 忽略NA
  3. ignore:NA值将不会被传递给映射函数
  4. raise:如果存在缺失值,则抛出异常
1
2
3
4
5
6
7
8
9
10
dct = {'name':['Python','Java','C++','Sql','Html','Css'],
'score':[90,30,np.nan,np.nan,78,np.nan],'pop':[65,43,np.nan,88,np.nan,90]}

df = pd.DataFrame(dct)
df

df['score'] = df['score'].map(lambda x: f'{x:.2f}', na_action=None)

df['pop'] = df['pop'].map(lambda x: f'{x:g}', na_action='ignore')
df
name score pop
0 Python 90.0 65.0
1 Java 30.0 43.0
2 C++ NaN NaN
3 Sql NaN 88.0
4 Html 78.0 NaN
5 Css NaN 90.0
name score pop
0 Python 90.00 65
1 Java 30.00 43
2 C++ nan NaN
3 Sql nan 88
4 Html 78.00 NaN
5 Css nan 90

字符串的替换 replace 函数

语法:

  1. string.replace(old,new,count)
    • string:要替换的字符串
    • old: (必选,字符串类型)被替换的字符串
    • new: (必选,字符串类型)替换后的字符串
    • count: (可选,整型)替换的次数
  2. str.replace(string,old,new,count)
    • old: (必选,字符串类型)被替换的字符串
    • new: (必选,字符串类型)替换后的字符串
    • count: (可选,整型)替换的次数
1
2
3
4
5
6
7
8
9
10
11
# 要做替换的字符串
a = '2023-11-10'

# 替换方式1
a.replace('-','')

# 替换次数 例如只替换 1 次
a.replace('-','',1)

# 指定替换次数为负数,则会全部替换.但是必须是整型int
a.replace('-','',-1)
'20231110'

'202311-10'

'20231110'
1
2
3
4
5
6
7
8
9
10
# 替换方式2
str.replace(a,'-','')

# replace() 不会改变原字符串的内容,而是返回一个新的字符串
a

# 连续替换
b ='I Love python'
b.replace('python','C++').replace('I','You')

'20231110'

'2023-11-10'

'You Love C++'
1
2
3
4
5
6
7
8
9
10
11
# 替换列表中的元素,获得新的列表
lst = [i for i in 'ABC']
lst
[i.replace('A','a') for i in lst]


# 替换字典中的键或值
dct ={k:v for v,k in enumerate(lst)}
dct

{k.replace('A','aa'):str(v).replace('1','100') for k,v in dct.items()}
['A', 'B', 'C']

['a', 'B', 'C']

{'A': 0, 'B': 1, 'C': 2}

{'aa': '0', 'B': '100', 'C': '2'}

字符串的替换 re.sub

语法:
re.sub(pattern, repl, string, count=0, flags=0)

  • pattern : 正则中的模式字符串。
  • repl : 替换的字符串,也可为一个函数。
  • string : 要被查找替换的原始字符串。
  • count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
1
2
3
4
5
6
7
8
9
10
11
12
13
a = 'address:123;number:456;date:789'
# 简单替换,将字符串中的 `:` 替换成 ` = `
re.sub(r':',' = ',a)


# reple 也可以是一个函数. 注意其中的函数 group()
repl = lambda x: '****' if x.group() == '123' else ('不允许公开的号码' if x.group() == '456' else '???')
re.sub(r'\d+',repl,a)

#
repl = lambda x: str(int(x.group()) + 100)
re.sub(r'\d+',repl,a)

'address = 123;number = 456;date = 789'

'address:****;number:不允许公开的号码;date:???'

'address:223;number:556;date:889'
1
2
3
4
5
6
7
8
9
10
11
file = r"C:\Users\xiaoyx\Desktop\231110\近三天均多头\231110_list.txt"

with open(file) as f1, open(f'{file}.bak','w',encoding='utf-8') as f2:
for line in f1:
# print(line)
# repl = lambda x :
f2.write(re.sub(r'\D+','',line))
os.remove(file)
os.rename(f'{file}.bak',file)
f1.close()
f2.close()
54

DataFrme 的值替换

  1. replace

    • df.replace(old,new)
    • df.replace({old:new,old,new})
  2. map

    • Series.map(arg,na_action =None)
      • arg : 映射一个 Series。它可以是一个集合或一个函数
      • na_action:处理 NaN(非数字)值。它可以取两个值-None 或 ignore。None 是默认值,map() 将把映射应用于所有值,包括 Nan 值;ignore 将 NaN 值留在列中,而不传递给映射方法。
  3. applymap

    • 语法:DataFrame.applymap(func, na_action=None, **kwargs)
    • func : 传入的函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
file = 'ddd.csv'
df = pd.read_csv(file,
# skiprows=[i for i in range(1,11)],
nrows=2,
parse_dates=['date'],
index_col='date',
)
df
# 将 bs列的 `0` 替换成 ` `, 将 `1` 替换成 `建仓`
df.replace(0,'').replace(1,'建仓')

# 将多个值替换成一个相同的值
df.replace([0,1],333)

# 字典形式, 字典的键:被替换的字符串,字典的值:替换后的字符串
## 实现用多个数值替换多个数值
df.replace({0:'',1:'建仓'})
open high low close volume turn ma05 ma10 ma20 bs
date
2020-02-21 3.180605 3.180605 3.143274 3.158207 9718154 0.9316 3.134315 3.099970 3.123489 0
2020-06-18 3.499128 3.518568 3.450529 3.518568 10729909 0.5944 3.464137 3.463165 3.464623 1
open high low close volume turn ma05 ma10 ma20 bs
date
2020-02-21 3.180605 3.180605 3.143274 3.158207 9718154 0.9316 3.134315 3.099970 3.123489
2020-06-18 3.499128 3.518568 3.450529 3.518568 10729909 0.5944 3.464137 3.463165 3.464623 建仓
open high low close volume turn ma05 ma10 ma20 bs
date
2020-02-21 3.180605 3.180605 3.143274 3.158207 9718154 0.9316 3.134315 3.099970 3.123489 333
2020-06-18 3.499128 3.518568 3.450529 3.518568 10729909 0.5944 3.464137 3.463165 3.464623 333
open high low close volume turn ma05 ma10 ma20 bs
date
2020-02-21 3.180605 3.180605 3.143274 3.158207 9718154 0.9316 3.134315 3.099970 3.123489
2020-06-18 3.499128 3.518568 3.450529 3.518568 10729909 0.5944 3.464137 3.463165 3.464623 建仓
1
2
3
4
5
6
7
8
df = pd.read_csv(file,
nrows=2,
parse_dates=['date'],
index_col='date',
)

df['open'] = df['open'].map(lambda x :f'{x :.2f}',na_action=None)
df
open high low close volume turn ma05 ma10 ma20 bs
date
2020-02-21 3.18 3.180605 3.143274 3.158207 9718154 0.9316 3.134315 3.099970 3.123489 0
2020-06-18 3.50 3.518568 3.450529 3.518568 10729909 0.5944 3.464137 3.463165 3.464623 1
1
2
3
4
5
6
7
8
9
10
df = pd.read_csv(file,
nrows=2,
parse_dates=['date'],
index_col='date',
)

df
df.applymap(lambda x :f'{x:.2f}',na_action=None)
df.applymap(lambda x :f'{x:.2f}',na_action='ignore')
df.applymap(lambda x :round(x,2))
open high low close volume turn ma05 ma10 ma20 bs
date
2020-02-21 3.180605 3.180605 3.143274 3.158207 9718154 0.9316 3.134315 3.099970 3.123489 0
2020-06-18 3.499128 3.518568 3.450529 3.518568 10729909 0.5944 3.464137 3.463165 3.464623 1
open high low close volume turn ma05 ma10 ma20 bs
date
2020-02-21 3.18 3.18 3.14 3.16 9718154.00 0.93 3.13 3.10 3.12 0.00
2020-06-18 3.50 3.52 3.45 3.52 10729909.00 0.59 3.46 3.46 3.46 1.00
open high low close volume turn ma05 ma10 ma20 bs
date
2020-02-21 3.18 3.18 3.14 3.16 9718154.00 0.93 3.13 3.10 3.12 0.00
2020-06-18 3.50 3.52 3.45 3.52 10729909.00 0.59 3.46 3.46 3.46 1.00
open high low close volume turn ma05 ma10 ma20 bs
date
2020-02-21 3.18 3.18 3.14 3.16 9718154 0.93 3.13 3.10 3.12 0
2020-06-18 3.50 3.52 3.45 3.52 10729909 0.59 3.46 3.46 3.46 1

loc方法替换列的值

语法:
DataFrame.loc[condition, column_label] = new_value

  1. condition:这个参数返回使条件为真的值。
  2. column_label:该参数用于指定要更新的目标列。
    通过参数确定值后,我们将其更新为 new_value。
1
2
3
4
5
6
7
8
9
10
df = pd.read_csv(file,
nrows=2,
parse_dates=['date'],
index_col='date',
)

df.loc[df.open > df.close,'bs'] = '收阴线'

df.loc[df.volume > 10000000, 'bs'] = '大成交量'
df
open high low close volume turn ma05 ma10 ma20 bs
date
2020-02-21 3.180605 3.180605 3.143274 3.158207 9718154 0.9316 3.134315 3.099970 3.123489 收阴线
2020-06-18 3.499128 3.518568 3.450529 3.518568 10729909 0.5944 3.464137 3.463165 3.464623 大成交量

字符串的修改

  1. replace() 返回替换后的字符串
  2. split() 返回切割后的列表序列
  3. str.join() 连接列表中的字符串
  4. lstrip() 去除左边空白字符
  5. rstrip() 去除右边的空白字符
  6. strip() 去除两边的空白字符
  7. ljust() 返回原字符串左对齐并填充位数
  8. rjust() 返回原字符串右对齐
  9. center() 返回原字符串居中对齐
  10. capitalize() 首字母大写
  11. title() 所有单词首字母大写
  12. upper()与lower() 返回全部大写或小写的字符串

str.replace(old, new[, max])

  • old – 将被替换的子字符串。
  • new – 新字符串,用于替换old子字符串。
  • max – 可选字符串, 替换不超过 max 次
1
2
3
4
# replace

a = 'I use python on Windows,you use Java on Linux'
a.replace('Windows','Mac')
'I use python on Mac,you use Java on Linux'

str.split(str="", num=string.count(str))

  • str:分隔符
  • num:分隔次数,默认为-1,分隔所有
1
2
3
4
# split
a = 'python,Java,json,c++'
a.split(',')
a.split(',',2)
['python', 'Java', 'json', 'c++']

['python', 'Java', 'json,c++']

str.join('symbol',sequence)

  • symbol:字符串连接符,可省略
  • sequence 要连接的元素序列,不可省略的参数,序列的元素是字符串
1
2
3
4
5
6
7
8
# join
a = ['I use python on Windows', 'you use Java on Linux']
str.join('; ',a)

# 或者
';'.join(a)

str.join(':','abc')
'I use python on Windows; you use Java on Linux'


'I use python on Windows;you use Java on Linux'

‘a:b:c’

string.strip(s[, chars])

  • 返回的是字符串的副本,并删除前导和后缀字符。
  • 如果strip()的参数为空,那么会默认删除字符串头和尾的空白字符(包括\n,\r,\t这些)
1
2
3
4
5
# lstrip,rstrip, strip
a = ' My hobby is computer programming '
a. lstrip()
a. rstrip()
a.strip()
'My hobby is computer programming  '

' My hobby is computer programming'

'My hobby is computer programming'
1
2
3
4
# strip
b = "aabcacb1111acbba"
b.strip('a')
b.strip('abc')
'bcacb1111acbb'
'1111'
1
2
3
# lstrip
b.lstrip('a')
b.lstrip('abc')
'bcacb1111acbba'

'1111acbba'
1
2
3
# rstrip
b.rstrip('a')
b.rstrip('abc')
'aabcacb1111acbb'

'aabcacb1111'

str.ljust(width[, fillchar])

  • width – 指定字符串长度。
  • fillchar – 填充字符,默认为空格。
1
2
3
4
5
6
7
8
# ljust,rjust,center

a ='I am 48 years old'
a.ljust(30,'-')

a.rjust(30,'-')

a.center(30,'-')
'I am 48 years old-------------'

'-------------I am 48 years old'

'------I am 48 years old-------'

str.capitalize() /title/upper/lower

  • capitalize:句首字母大写
  • title:每个单词首字母大写
  • upper:全部大写
  • lower:全部小写
1
2
3
4
5
6
7
8
9
10
a ='python,Java,json,c++'
b = a.split(',')
b
list(map(lambda x: x.capitalize(),b))

list(map(lambda x: x.title(),b))

list(map(lambda x: x.upper(),b))

list(map(lambda x: x.lower(),b))
['python', 'Java', 'json', 'c++']

['Python', 'Java', 'Json', 'C++']

['Python', 'Java', 'Json', 'C++']

['PYTHON', 'JAVA', 'JSON', 'C++']

['python', 'java', 'json', 'c++']

1
2
3
4
5
6
7
8
9
10
11
12
import os, re
import random
import numpy as np
import pandas as pd
from datetime import date, datetime, timedelta

from pyecharts.charts import Kline, Line, Bar, Grid,Map,Pie,Timeline,Geo
from pyecharts.commons.utils import JsCode
from pyecharts import options as opts
from pyecharts.globals import CurrentConfig, NotebookType,ThemeType,ChartType, SymbolType
from pyecharts.faker import Faker

K线图

  1. 准备数据
  2. 设置kline K线图
  3. 设置line 均线图
  4. 设置bar 成交量
  5. 图表叠加 K线图和均线图
  6. 图表组合 叠加完成的图表与成交量条形图组合
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
## --------------绘图数据-----------------
file = r"D:\Stock_data\kdata\603956.csv"
code = re.findall(r'\d{6}',file)[0]
df = pd.read_csv(r"D:\Stock_data\kdata\603956.csv",
index_col="date",
parse_dates=["date"],
usecols=[0,1,2,3,4,5,6]
)
df["ma5"] = df["close"].rolling(5).mean()
df["ma10"] = df["close"].rolling(10).mean()
df["ma20"] = df["close"].rolling(20).mean()
df = df[df.index >= '2022-06-01']
df.dropna(inplace=True)
df['ma5'] = df['ma5'].map(lambda x :round(x,2))
df['ma10'] = df['ma10'].map(lambda x :round(x,2))
df['ma20'] = df['ma20'].map(lambda x :round(x,2))
df.head()
date = list(map(lambda x: x.strftime("%Y-%m-%d"), df.index.tolist()))
kl_data = df[["open", "close", "low","high"]].values.tolist()
l_data = df[["ma5", "ma10", "ma20"]].values.tolist()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#-------------设置kline-------------------
k = (Kline(init_opts=opts.InitOpts(width="100%", height="800px"))
.add_xaxis(date)
.add_yaxis("kline",kl_data).set_global_opts(
datazoom_opts=[
opts.DataZoomOpts(type_="inside",range_start=0,range_end=100),
opts.DataZoomOpts(type_="slider",xaxis_index=[0,1],is_show=True),
],
title_opts=opts.TitleOpts(
title="K线图",
subtitle=f"股票代码:{code}",
),
toolbox_opts=opts.ToolboxOpts(),

)

)
k.render_notebook()
k.render('1.html')
Awesome-pyecharts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# -----------------均线 折线图---------------
l =(Line(init_opts=opts.InitOpts(width="100%", height="800px")).add_xaxis(date)
.add_yaxis("ma5",
df['ma5'].values.tolist(),
symbol = None,
is_symbol_show=False,
label_opts=opts.LabelOpts(is_show=False),
markpoint_opts=opts.MarkPointOpts(data=[
{"yAxis": 150}, # 增加自定义标记线
opts.MarkPointItem(type_="min"),
opts.MarkPointItem(type_="max"),
opts.MarkPointItem(type_="average")])
)
.add_yaxis("ma10",
df['ma10'].values.tolist(),
is_symbol_show=False,
label_opts=opts.LabelOpts(is_show=False),
)
.add_yaxis("ma20",
df['ma20'].values.tolist(),
is_symbol_show=False,
label_opts=opts.LabelOpts(is_show=False),
)
)
l.render_notebook()
l.render('2.html')
Awesome-pyecharts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
v =  (Bar()
.add_xaxis(xaxis_data=date).add_yaxis(
series_name="volume",
y_axis=df["vol"].tolist(),
xaxis_index=1,
yaxis_index=1,
label_opts=opts.LabelOpts(is_show=False),
itemstyle_opts=opts.ItemStyleOpts(color=JsCode("""
function(params) {
var colorList;
if (barData[params.dataIndex][1] > barData[params.dataIndex][0]) {
colorList = '#ef232a';
} else {
colorList = '#14b143';
}
return colorList;
}
""")),
)
.set_global_opts(
xaxis_opts=opts.AxisOpts(
type_="category",
grid_index=1,
axislabel_opts=opts.LabelOpts(is_show=False),
),
legend_opts=opts.LegendOpts(is_show=False),
))
1
2
3
4
5
# ---------------------叠加图表----------------------
ov1 = k.overlap(l)
ov1.render_notebook()
ov1.render('3.html')

Awesome-pyecharts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 ov = k.overlap(l)

g = (Grid(init_opts=opts.InitOpts(
width="1600px",
height="800px",
animation_opts=opts.AnimationOpts(animation=False),
)
)
.add_js_funcs("var barData={}".format(df[["open", "close"]].values.tolist()))
.add(ov,
grid_opts=opts.GridOpts(
pos_top="2%",
height="70%",
),
)
.add(v,
grid_opts=opts.GridOpts(
pos_top="76%",
height="20%",
),)
)

g.render_notebook()
g.render("4.html")

Awesome-pyecharts

1
2
3
4
5
6
7
8
9
10
11
12
import os, re
import random
import numpy as np
import pandas as pd
from datetime import date, datetime, timedelta

from pyecharts.charts import Kline, Line, Bar, Grid,Map,Pie,Timeline,Geo
from pyecharts.commons.utils import JsCode
from pyecharts import options as opts
from pyecharts.globals import CurrentConfig, NotebookType,ThemeType,ChartType, SymbolType
from pyecharts.faker import Faker

其他种类图表的基本用法

折线图

  1. is_smooth = False,# 是否平滑曲线
  2. is_connect_nones = False, # 是否连接空数据
  3. is_step = False, # 是否展示为阶梯图
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
line = (Line()
.add_xaxis(Faker.choose())
.add_yaxis('B',Faker.values())
.add_yaxis('C',Faker.values())
.add_yaxis('D',Faker.values())
.set_series_opts(
markpoint_opts=opts.MarkPointOpts(
data=[
opts.MarkPointItem(type_="max", name="x轴最大",value_index=1)
]),
)
)

line.render_notebook()
line.render('1.html')
Awesome-pyecharts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
c = (Pie().add("",
[list(z) for z in zip(["古装", "其他"], [35, 65])],
center=["20%", "30%"],
radius=[50, 80],
# label_opts=new_label_opts(),
)
.add(
"",
[list(z) for z in zip(["动作", "其他"],[24, 76])],
center=["55%", "30%"],
radius=[50, 80],
# label_opts=new_label_opts(),
)
.add(
"",
[list(z) for z in zip(["爱情", "其他"],[10, 90])],
center=["20%", "70%"],
radius=[50, 80],
label_opts=opts.LabelOpts(is_show=True),
)
.add(
"",
[list(z) for z in zip(["惊悚", "其他"],[20, 80])],
center=["55%", "70%"],
radius=[50, 80],
label_opts=opts.LabelOpts(is_show=True),
)
.set_global_opts(
title_opts=opts.TitleOpts(title="Pie-多饼图基本示例"),
legend_opts=opts.LegendOpts(
type_="scroll",
pos_top="30%",
pos_left="70%",
orient="vertical"
),
)
)
c.render_notebook()
c.render('2.html')
Awesome-pyecharts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
c = (Pie()
.add(
"",
[list(z) for z in zip(Faker.choose(), Faker.values())],
radius=["40%", "75%"],
center=["35%", "50%"],
rosetype="radius",
label_opts=opts.LabelOpts(is_show=True),
)
.set_global_opts(
title_opts=opts.TitleOpts(
title="饼图-玫瑰图示例"))
)
c.render_notebook()
c.render('3.html')
Awesome-pyecharts
1
2
3
4
5
6
7
8
9
10
11
12
13
c = (Map()
.add(
"商家A",
[list(z) for z in zip(["杭州市", "宁波市", "舟山市", "台州市", "温州市", "丽水市", "金华市", "衢州市", "绍兴市", "湖州市", "嘉兴市"], Faker.values())], "浙江")
.set_global_opts(
title_opts=opts.TitleOpts(
title="Map浙江地图-Test"),
visualmap_opts=opts.VisualMapOpts()
)
)

c.render_notebook()
c.render('4.html')
Awesome-pyecharts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
attr = Faker.choose()
tl = Timeline()
for i in range(2015, 2022):
pie = (Pie()
.add(
"商家A",
[list(z) for z in zip(attr, Faker.values())],
center=["50%", "50%"], radius=["40%", "60%"],
)
.set_global_opts(title_opts=opts.TitleOpts(
"某商店{}年营业额".format(i)
)
)
)
tl.add(pie, "{}年".format(i))
tl.render_notebook()
tl.render('5.html')
Awesome-pyecharts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
c = (Bar()    
.add_xaxis(Faker.choose())
.add_yaxis("商家1", Faker.values(),
category_gap="50%")
.set_series_opts(
itemstyle_opts={
"normal": { "color": JsCode("""
new echarts.graphic.LinearGradient(0, 0, 0, 1, [{offset: 0, color: 'rgba(0, 244, 255, 1)' },
{offset: 1,color: 'rgba(0, 77, 167, 1)'}],
false
)
"""
),
"barBorderRadius": [50, 50, 50, 50],
"shadowColor": "rgb(0, 160, 221)",
}
}
)
.set_global_opts(
title_opts=opts.TitleOpts(
title="圆角直方图-渐变圆柱示例"
)
)
)
c.render_notebook()
c.render('6.html')
Awesome-pyecharts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
c = (Map()
.add(
"商家1",
[list(z) for z in zip(Faker.provinces, Faker.values())], "china")
.set_global_opts(
title_opts=opts.TitleOpts(
title="地图 + 颜色分段(连续型)"
),
visualmap_opts=opts.VisualMapOpts(
max_=150),
)
)
c.render_notebook()
c.render('7.html')
Awesome-pyecharts
1
2
3
4
5
6
7
8
9
10
11
12
13
c = (Map()    
.add(
"商家1",
[list(z) for z in zip(Faker.country, Faker.values())], "world"
)
.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
.set_global_opts(
title_opts=opts.TitleOpts(title="Pyecharts-世界地图"),
visualmap_opts=opts.VisualMapOpts(max_=200),
)
)
c.render_notebook()
c.render('8.html')
Awesome-pyecharts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
c = (Geo()    
.add_schema(
maptype="china",
itemstyle_opts=opts.ItemStyleOpts(color="#323c48", border_color="#111"),
)
.add(
"",
[list(z) for z in zip(Faker.provinces, Faker.values())],
type_=ChartType.EFFECT_SCATTER,
color="white",
)
.add(
"geo",
[("宁波", "南京"), ("宁波", "北京"), ("宁波", "兰州"), ("宁波", "拉萨"), ("宁波", "银川"), ("宁波", "武汉")],
type_=ChartType.LINES,
effect_opts=opts.EffectOpts(
symbol=SymbolType.ARROW,
symbol_size=6, color="blue"
),
linestyle_opts=opts.LineStyleOpts(curve=0.2),
)
.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
.set_global_opts(
title_opts=opts.TitleOpts(
title="Geo-Lines-background"
)
)
)
c.render_notebook()
c.render('9.html')
Awesome-pyecharts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
tl = Timeline()
for i in range(2015, 2022):
map0 = (Map()
.add(
"商家1",
[list(z) for z in zip(Faker.provinces, Faker.values())],
"china"
)
.set_global_opts(
title_opts=opts.TitleOpts(
title="{}年数据".format(i)
),
visualmap_opts=opts.VisualMapOpts(max_=200),
)
)
tl.add(map0, "{}年".format(i))
tl.render_notebook()
tl.render('10.html')
Awesome-pyecharts