五个月过的害挺快捏🎶🎶🎶🎶🎶

第一篇日记在2021/11/25

而今天正好是2022/04/24

好快哦

五个月就这么过去了

刚刚网页滑了好久都没滑倒底

心里看着自己的努力

还是很有成就感的

7

毕竟自己也很少有坚持这么久的事情

可能都不是喜欢在驱动

因为这些事情我觉得不需要驱动

就像我喜欢你一样

是一件自然而然的事情

我也并不把这些片段当成是考验

喜欢哪用的着顾虑这么多呢

我不知道明天会怎么样

不知道后天会怎么样

也不知道一个月后会怎么样

但我能知道的是

明天我还是会依然喜欢你

后天我会更喜欢你

一个月后会接着中意你

你啊

从来都没有让我头疼过

8

还是很替宝贝你开心的哦oooo

最近看到宝贝每天工作都是比较认真的样子

可以有空学一些自己想学的东西

做一些自己想做的事情

身边的领导也能够给你很多的尊重

这点我挺开心的

有一些恶心人的鬼玩意

那些人我和你一样

向来是看不起的

不会给予正面的评价

262

回到正题

就像我一直说的

我希望你去做自己想做的事情

这中间我也不希望自己是一个搅局者或者说是骚扰者

我会一直陪在你旁边

不是以四维的方式

但是不知道你有没有画过连环画

很多连环画一页一页累计

仍然会是一个完整而充满生机的故事

必不可免的

我会感受到些许落寞

263

但你总会是治愈我的那一个存在

而我也希望自己

能成长为

学习成为

你需要的另一半

记忆会有变淡的一天

但感情不会

我仍期待着与你的下一次相会

那时候

我会笑得最为坦然

264

我是你的明文,你是我的密文

连着好几天都没咋和宝贝你说心里话了

今天就多说说吧

其实自从你回来之后

心里其实一直都悬着

你问我害不害怕

那我肯定是非常害怕的

260

当听到你说他给你买了电脑的时候

一瞬间像是被针扎了一般

261

再怎么云淡风轻也欺骗不了自己

但是emo是一时的

喜欢确实长长久久的

至今

我仍很开心能够倾心于你

半年对我来说并不是一个了不得的期限

相反,时间的延续反而会让我看清楚自己的内心

看清楚有些喜欢的纯粹

我过着有点像是苦行僧一般的生活

每天重复的工作,睡觉,看球赛,吃饭

但是负面情绪从来都不会出现在我的脑海里

可能是因为脑海里都是你和关于你的记忆

所以悲伤都无处遁逃了吧

我从来都没有和你卖过惨

没有突兀的出现去吓你

因为我们俩都太了解彼此了

我们是同类人

我知道你不喜欢什么

常年的默契

或者我更愿意把这种心有灵犀当作是一种缘分

拿密码学里面的术语来说

我们互为彼此的明文和密文

就算隔着千里之外

通过一点一滴我依然能感受到你情绪的浮动

你也能感受到我的心灵触角

这对我来说难能可贵

这可能也是

有你在

我总是会觉得自己过的更从容的原因

不知不觉也罗里吧嗦的说了不少

我变了很多

发型,穿搭,习性…..

但有些事情一直都没有变

而你知道的💕💕💕💕💕💕💕💕

kz_filter项目解析(三)

今天看的主要是detrend.py这个文件的实现逻辑

我感觉前两天走的公式逻辑以及kz_filter代码逻辑还是有帮助的

背景足够熟悉,接下来无论是实现的场景还是设计的思路都能更加清楚

首先我看了一下代码的结果出图,在kzfilter-master\detrend*.png**里面

样例代码用的是input=9,也就是Tsuen wan城市

结果为

![Tsuen Wan](/images/Tsuen Wan.png)

由结果推论,可得四个主要数据,分别为

  • Log-transformed O3 (经log自然指数e转型后o3数据曲线)
  • O3 Short Term Component (短期o3数据指数,)
  • O3 Seasonal Term Component (季度o3数据指数)
  • O3 Long Term Component (年度o3数据指数)

接下来我们走代码

  1. 分段走的话,第一步看文件处理,这里主要将不同地区数据存入file或者file1和file2中
1
2
3
4
5
6
7
8
9
10
11
12
filelist = ['Eastern', 'Kwai Chung', 'Tung Chung', 'YL', 'Kwun Tong', 'Macau', 'Sha Tin', 'ShamShuiPo', 'Tap Mun',
'Tsuen Wan']
# Put Your input between 0 and 9
input = 9
test = filelist[input]
if input < 4:
file = "Supplement/O3-KZ/" + test + ".csv"
else:
file = "Supplement/O3-KZ/O3-supplement/" + test + "-1.csv"
file2 = "Supplement/O3-KZ/O3-supplement/" + test + "-2.csv"
subplot_matrix = []
print(test)
  1. 下一步是数据预处理的读取过程,这一步不需要多说

    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
    def detrend(file):
    hours = 24
    timestamp = []
    height = []
    o3 = []
    source = []
    status = []
    details = []
    delete_index = []
    with open(file) as infile:
    # 读取当前o3数据文件
    reader = csv.reader(infile)
    # 遍历往时间数组,o3值数组,状态数组填值
    for rows, value in enumerate(reader):
    if rows > 3:
    timestamp.append(value[0])
    height.append(float(value[1]))
    o3.append(float(value[2]))
    source.append(value[3])
    status.append(float(value[4]))
    details.append(float(value[5]))
    if input > 3:
    with open(file2) as infile:
    reader = csv.reader(infile)
    # 遍历往时间数组,o3值数组,状态数组填值
    for rows, value in enumerate(reader):
    if rows > 3:
    timestamp.append(value[0])
    height.append(float(value[1]))
    o3.append(float(value[2]))
    source.append(value[3])
    status.append(float(value[4]))
    details.append(float(value[5]))
  2. 接下来将存放的数据进行进一步处理,主要用于截取所需时间段的数据,并精简数据量(每天只取一个小时的数据作为标志数据),具体请看对应行注释

    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
    # 如果是Macau数据,只统计在2013-2015年的数据
    if input == 5:
    timestamp = timestamp[:-17543]
    o3 = o3[:-17543]
    # Tsuen Wan: Delete from 2003/08/19 (2003/02/12 [973] ~ 2003/08/19 [5574])
    if input == 9:
    o3 = o3[5574:]
    timestamp = timestamp[5574:]
    numberofelements = len(timestamp) # 157800
    # 数据都是一小时取一次,所以数组的长度等于小时数,计算后可得天数
    numberofday = int(numberofelements / hours) # 6575 days
    daily_timestamp = []
    # 这一个过程是确定一天只取最后一小时数据,返回daily_timestamp数组
    for i in range(numberofelements):
    if i % 24 == 23:
    today = timestamp[i].split()[0]
    daily_timestamp.append(today)
    print(daily_timestamp)

    for i in range(len(timestamp)):
    if o3[i] < 0:
    delete_index.append(i)
    print(numberofday, "days")
    # delete_index是取出数据值小于0的非法值
    print("Delete:", delete_index)
    # findPositive方法可以取非法值前后的各第一个正常值,取其平均再存到o3数据列表中
    for j in range(len(delete_index)):
    o3[delete_index[j]] = functions.findPositive(o3, delete_index[j])
    print("First Row:", timestamp[0], height[0], o3[0], source[0], status[0], details[0])
    # 打印o3数据平均值
    print("Mean", round(mean(o3), 4))
    # 取选中数据的每天平均值存放到数组里
    daily = functions.Daily(o3)
    x = np.array(daily)
    # t = np.arange(0, numberofday, dt)
    t = np.array(daily_timestamp)
  3. 至此准备工作完成,进行第一幅月度log曲线图(以此为例,后面类似)

    首先定义数据,对应到公式里面的m,k,t

    1
    2
    3
    4
    5
    6
    7
    # 以月度为周期统计o3数据变化值
    m = 29
    k = 3
    # 取选中数据的每天平均值存放到数组里
    daily = np.array(daily)
    # 生成daily的自然对数底数e(2.71828)对应的log值数组,这是为了使得减小数据的纵向差值
    daily = np.log(daily)

    之后把数据带入公式中并append到结果集合

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 得到kz_filter之后的结果集合
    o3_bl = kz_filter(daily, m, k)
    # Adjust time
    # 这里的w是我们之前在公式推导中所需要用到的遍历范围值
    w = int(k * (m - 1) / 2)
    # daily_timestamp2可以把数据从daily_timestamp得到-w到w的区间值
    daily_timestamp2 = daily_timestamp[w:-w]
    # 将月度数据放进subplot_matrix结果集合中
    subplot_matrix.append([daily_timestamp, daily, daily_timestamp2, o3_bl])
  4. 将几组数据处理完成后,进行图像绘制工作,这一部分逻辑比较简单,就不过多赘述了

    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
    detrend(file)
    # Subplot
    fig = plt.figure(figsize=(20, 8))
    plt.suptitle(filelist[input], fontsize=20)
    for count in range(len(subplot_matrix)):
    data = subplot_matrix[count]
    ax = plt.subplot(2, 2, count + 1)
    ax.grid(True)
    if count == 0:
    ax.plot(data[0], data[1], label='Daily Data')
    ax.plot(data[2], data[3], label='Baseline (O3 BL)')
    ax.legend(loc='best')
    else:
    ax.plot(data[0], data[1])
    ax.xaxis.set_major_locator(plt.MaxNLocator(5)) # Set Maximum number of x-axis values to show
    if count == 0:
    titles = 'Log-transformed O3'
    plt.ylabel("ppb (log-scaled)", fontsize=15)
    elif count == 1:
    titles = 'O3 Short Term Component'
    plt.ylabel("[O3 ST]", fontsize=15)
    elif count == 2:
    titles = 'O3 Seasonal Term Component'
    plt.ylabel("[O3 SEASON]", fontsize=15)
    else:
    titles = 'O3 Long Term Component'
    plt.ylabel("[O3 LT]", fontsize=15)
    plt.title(titles, fontsize=18)
    plt.tight_layout()
    plt.subplots_adjust(wspace=0.15, top=0.9)

kz_filter项目解析(二)

昨天公式大概看了一下(虽然还是有点没大看懂哈哈哈,但是感觉有点思路了 )

今天代码走起

首先他这个样例代码和kolzur_filter.py库代码并没有太多关联关系

所以我打算自己先自定义一些变量来实践一下kolzur_filter内部的逻辑过程

python不是很熟悉

遇到一些不会的地方就多写写注释了

我们首先拆分一下kolzur_filter内部的kz_filter函数(其实他的英文注释已经有了一些,但还是想自己理解一下🤭)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def kz_filter(data, m, k):
"""首先看一下参数的使用,分别代表了什么
: data 这里的data是一个集合,是一个大小为N的一阶随机数集合,数据丢失就用“”空字符串代替,确保长度对上
: m m是一个滤波器的长度(移动平均窗口的长度)
: k k是移动平均窗口的迭代次数
: 返回值 返回值是一个元素数量为N-k*(m-1)的集合

之后我们会给定一个时间序列集合data 这个集合是可以自己去声明的,一个随机序列,后面我们再去赋值测试

"""

coef = _kz_coeffs(m, k)
data = _kz_prod(data, coef, m, k)

return _kz_sum(data, coef)

其实我们昨天有个最基本的公式是

253

然后其实这里的kz_filter函数就是左侧这个出参

后面我们写的_kz_coeffs函数是这个乘以左侧遍历的结果

255

第一步就是先进行_kz_coeffs函数的计算(计算系数)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
ef _kz_coeffs(m, k):
"""

:会返回一个长度为`k*(m-1)+1`的集合结果
这是一个可以直接调用的功能函数不用深究,会用就行
"""

# Coefficients at degree one
coef = np.ones(m)

# Iterate k-1 times over coefficients
for i in range(1, k):
# np.zeros()函数返回一个元素全为0且给定形状和类型的数组
t = np.zeros((m, m+i*(m-1)))
for km in range(m):
t[km, km:km+coef.size] = coef

coef = np.sum(t, axis=0)

assert coef.size == k*(m-1)+1

print(coef/m**k)
return coef/m**k

再然后是根据给定时间序列T进行下一步运算

1
2
3
4
5
6
7
8
9
10
11
12
13
def _kz_prod(data, coef, m, k, t=None):

n = data.size
#调用了sliding_window函数,后面详解
data = sliding_window(data, k*(m-1)+1)
assert data.shape == (n-k*(m-1), len(coef))

# Restrict KZ product calculation to provided indices
if t is not None:
data = data[t]
assert data.shape == (len(t), len(coef))

return data*coef

接上一步看看sliding_window函数用法

1
2
3
4
5
6
7
8
9
10
11
12
def sliding_window(arr, window):
"""未来在numpy阵列上生成滑动窗口,其实也不用管太多
:arr 这里是传进来的时间轴序列
:window 这里是窗口长度,也就是遍历的长度k*(m-1)+1
:return: A :class:`numpy.ndarray` of shape `(n1, ..., nN-window+1, window)`.
"""

# arr.shape[:-1]是用来返回arr除最后一位的所有值
shape = arr.shape[:-1] + (arr.shape[-1]-window+1, window)
# arr.strides是用于得到时间序列的跨度
strides = arr.strides + (arr.strides[-1],)
return np.lib.stride_tricks.as_strided(arr, shape=shape, strides=strides)

暂且到这里可以将代码和大概的计算逻辑相结合,后面需要的应该是对于数据的处理以及项目的构建

kz_filter项目解析(一)

答应了要和你一起看的,今天就先从基本概念学起吧

就是数学好久都没看了哦,小脑袋瓜不够用了

104

理解什么是移动平均线(Moving average)

  1. 移动平均线是一种创建完整数据集的不同子集的一系列平均值来分析数据点的计算

  2. 一般会有给定的集合和固定的子集大小两个参数

  3. 大体的思路是:

    • 首先计算初始集合的平均值作为第一个元素,然后每一次向后移动都会用到前一个元素

    • 通常会和时间序列一起使用

    • 每一个平均值点k的值为

      250

    • 这样子就可以建立起一个均值点k和他前一个点的联系

    接下来看一下KZ滤波器的公式大体推理

    首先是要建立集合长度m,迭代当前次数k,当前时间点t的关联关系

251

之后我们拿一个实例来看可能更清楚一点

当第一次迭代时,k=1

252

你回来了,我也从来都没有离开过

终于回来啦

96

在一个陌生的

遥远而又冷漠的城市

感受着生活,工作,疫情等等的不安

说实话真心觉得崽崽挺不容易的

92

这个城市实在是糟糕的不行

还有那些讨厌的人

卢局,康主任,ljm….

不断打磨着对生活的热情

我没办法帮太多忙

却一直都和你感同身受

好在终于等到了春天

现在终于可以回来啦

就像是一场梦

跨越了半年的一场梦

从你的生日梦到了我的生日

我更想这是个以往一直以来的美梦

醒来就能看到你

牵着你的手

亲吻你的额头

我一直都在这里

一直都在期待着你……