第一次试飞

前天五四青年节提前下班,回家迫不及待的把我的四轴拿出去飞了下,毫无悬念,炸鸡了。损失不是太大,脚架断了一根,电调一个电感坏了,去网上买了根16mm碳纤管、22uh电感,等到货了再修理下。
炸鸡主要有以下几点导致的:
– 四个电机电调没有校准好,转速不太一致
– 飞控的水平没有校准好,导致飞的时候老是往一边偏
– 没有合适的长地,不太敢飞,忽高忽低,操作不方便,以后去空旷的地方比较好

组四轴无人机总结

最近组装了个四轴无人机,轴距650mm,负载4KG+,踩了一些坑,分享下。

基本组成:

  • 机架:飞越650
  • 电机:朗宇380KV
  • 电调:好赢40A
  • 飞控:PixHawk
  • GPS:Ublox M8N
  • 桨:1555碳纤桨
  • 桨座:快拆桨座
  • 电池:6S 10000MAH
  • 遥控器:FrSky X7
  • 接收机:FrSky X8R
  • 充电器:B6平衡充
  • 信号线:22AWG硅胶线
  • 电源线:14AWEG硅胶线
  • 接头:2.54mm镀金杜邦端子、杜邦外壳,XT60公头、母头
  • 焊接工具:烙铁或吹焊机、松香、焊锡、镊子(如果用烙铁买大功率点,不然焊接头不太容易)
  • 辅助设备:万用表、螺丝刀、剥线器、剪刀、钳子、皮筋(绑在钳子上可以固定接头)
  • 辅助材料:魔术贴(捆绑设备、电池)、尼龙扎带、热缩管、3M双面胶
  • 螺丝:M2 M2.5 M3螺丝,长度不定,不确定螺丝内径可以用游标卡尺或千分尺测量,也可用细线绕10圈测量,普通尺子不行
  • 电流计:非必须
  • 数传:非必须
  • OSD:非必须
  • 图传:非必须
  • 空速计:非必须

注意事项

  • 玩航模很烧钱很费时间,效果还可能不理想,还可能不让在家周围飞,量力而行
  • 国内电子设备假货泛滥,低端仿制很多,注意辨别,尤其是飞控、GPS这种设备
  • 提前设计好设备的安装位置和线长,保证机架整洁,强迫症可以忽略
  • 飞控最后安装,提前调试好,不然要来回拆卸
  • 调试指南针的时候远离一起可能干扰源,不然结果是不准确的
  • 注意安全,不到最后一步万万不可安装螺旋桨,非常危险,安装的时候注意正反桨
  • 多学习,多看文档,国内社区水平不高建议看国外论坛

附录

PixHawk飞控接线图

飞机选装方向与桨叶的安装
  • CW 顺时针螺旋桨,绿色图示
  • CCW逆时针螺旋桨 ,蓝色图示
遥控器控制类型

遥控器常见的一共有2个控制模式:
– Model1 日本手:左边的摇杆控制 Pitch俯仰 和 YAW方向,右边的摇杆控制 Throttle油门和ROLL横滚

– Model2 美国手:左边的摇杆控制 Throttle油门 和YAW方向,右边的摇杆控制 Pitch俯仰和ROLL横滚

YAW 偏航是绕Z轴旋转 Pitch是俯仰绕Y轴旋转,ROLL横滚绕X轴旋转(X轴为飞机前进方向)

解锁飞行器
  • 在解锁之前,请确保在一个空旷无人的环境进行测试,以免出现意外情况。
  • 详细检查硬件安装是否正确(特别是电调插线、飞行器固件、螺旋桨方向),确认没有问题之后,执行以下步骤
  • 打开你的遥控器发射机
  • 将电池插入到飞行器。飞控状态灯应该是红色蓝色交替闪烁(自检过程),自检中不要移动飞行器
  • Pre-Arm将自动运行,正常自检后,会 闪烁 蓝色灯 或者 绿色灯, 说明Pre-arm无错误,可以解锁。如果 闪烁黄色灯 ,请参照上一个章节 Pre-Arm 报错信息分析 指南进行排除错误
  • 设置正确模式 :将模式设置为 增稳Stabilize、 定高ATLhold 或者定点Loiter(需要室外GPS锁定) 新手推荐使用增稳或者定高
  • 解锁安全开关: 长按解锁安全开关,直到安全LED常亮状态(闪烁为锁定不输出pwm信号,常亮为解锁输出pwm信号)
  • 解锁遥控器:将遥控器油门打到最低,YAW方向达到最右,保持10秒,RGB状态灯会红蓝交替闪烁,完成解锁,松开YAW
  • 成功解锁:螺旋桨将怠速旋转起来,看起来是有点恐怖,但是这个一个安全设置,提醒已经成功解锁。可以通过MOT_SPIN_ARMED参数调整速度或者为0关闭
  • 起飞:推高油门起飞,并根据姿态去控制方向(如果新手不熟悉控制,可以先去练习飞行模拟器,以免出现炸鸡而造成人员和财产损失)
  • 如果解锁后,15秒内无任何操作,将会自动上锁,解锁后在未起飞的状态下,理想的姿态跟实际姿态相差过大会自动上锁(如大幅度打roll杆或者用手晃动飞行器)
上锁飞行器

上锁飞行器执行以下操作:
– 检查你的飞行模式开关设置为 Stabilize增稳 、定高 AltHold 或者 定点 Loiter
– 油门保持最低和方向YAW最左 (与解锁反方向)
– 按住 安全开关-直到闪烁
– 拔掉飞行器电池
– 关闭遥控器发射机

Pandas 入门

整理了Pandas的一些基础用法,以前学习的时候写在Jupyter上。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
s=pd.Series([1,2,3,np.nan,5,6])
s
0    1.0
1    2.0
2    3.0
3    NaN
4    5.0
5    6.0
dtype: float64
dates=pd.date_range("20170101",periods=20)
dates
DatetimeIndex(['2017-01-01', '2017-01-02', '2017-01-03', '2017-01-04',
               '2017-01-05', '2017-01-06', '2017-01-07', '2017-01-08',
               '2017-01-09', '2017-01-10', '2017-01-11', '2017-01-12',
               '2017-01-13', '2017-01-14', '2017-01-15', '2017-01-16',
               '2017-01-17', '2017-01-18', '2017-01-19', '2017-01-20'],
              dtype='datetime64[ns]', freq='D')
np.random.randint(10,size=(2,5))
array([[6, 4, 1, 8, 0],
       [0, 4, 3, 0, 1]])
df1=pd.DataFrame(np.random.randn(20,4),index=dates,columns=["a","b","c","d"])
df1
a b c d
2017-01-01 -0.731296 0.308452 1.550586 0.022510
2017-01-02 0.011909 -2.604560 -0.328210 -0.831059
2017-01-03 1.016461 -0.340761 1.399342 1.435456
2017-01-04 -0.610496 -0.962359 -0.397980 0.833718
2017-01-05 1.298400 -0.148515 -1.366670 0.718973
2017-01-06 0.265090 0.490953 1.048929 -0.611945
2017-01-07 -0.718811 1.640064 -1.063297 -1.092510
2017-01-08 -0.686471 0.541123 0.415082 0.368303
2017-01-09 0.352406 -0.061781 1.385387 0.240791
2017-01-10 -0.750252 -0.353765 0.163297 -0.706397
2017-01-11 1.707390 1.000258 0.717216 -0.566941
2017-01-12 -0.341289 0.742661 -1.820184 -0.182327
2017-01-13 -0.583300 -0.490837 -0.611798 -1.238514
2017-01-14 0.285966 1.219942 1.679262 0.170911
2017-01-15 -0.100615 -0.111391 1.827916 0.359999
2017-01-16 0.834599 0.214739 -0.868497 0.637817
2017-01-17 1.233904 -0.296525 -0.218316 0.651542
2017-01-18 2.211547 1.652226 1.415402 -1.023644
2017-01-19 0.176992 0.228890 0.844449 1.267496
2017-01-20 -0.242708 -0.792746 0.377210 0.521628
df2=pd.DataFrame({"A":range(11,20),"B":pd.Timestamp("20170101"),"C":pd.Series(np.random.random(9),index=range(11,20)),"D":np.array([i for i in range(1,10)]),
                 "E":pd.Categorical(["one","two","three","four","five","six","seven","eight","nine"])})
df2
A B C D E
11 11 2017-01-01 0.115527 1 one
12 12 2017-01-01 0.966706 2 two
13 13 2017-01-01 0.627952 3 three
14 14 2017-01-01 0.858634 4 four
15 15 2017-01-01 0.512081 5 five
16 16 2017-01-01 0.986166 6 six
17 17 2017-01-01 0.963712 7 seven
18 18 2017-01-01 0.754798 8 eight
19 19 2017-01-01 0.184086 9 nine

基础操作

df2.head()
A B C D E
11 11 2017-01-01 0.115527 1 one
12 12 2017-01-01 0.966706 2 two
13 13 2017-01-01 0.627952 3 three
14 14 2017-01-01 0.858634 4 four
15 15 2017-01-01 0.512081 5 five
df2.tail(2)
A B C D E
18 18 2017-01-01 0.754798 8 eight
19 19 2017-01-01 0.184086 9 nine
df2.index
Int64Index([11, 12, 13, 14, 15, 16, 17, 18, 19], dtype='int64')
df2.columns
Index([u'A', u'B', u'C', u'D', u'E'], dtype='object')
df2.values
array([[11L, Timestamp('2017-01-01 00:00:00'), 0.11552714551146004, 1,
        'one'],
       [12L, Timestamp('2017-01-01 00:00:00'), 0.9667064772135637, 2, 'two'],
       [13L, Timestamp('2017-01-01 00:00:00'), 0.6279515096467739, 3,
        'three'],
       [14L, Timestamp('2017-01-01 00:00:00'), 0.8586339869062394, 4,
        'four'],
       [15L, Timestamp('2017-01-01 00:00:00'), 0.5120808880213029, 5,
        'five'],
       [16L, Timestamp('2017-01-01 00:00:00'), 0.9861662616379155, 6, 'six'],
       [17L, Timestamp('2017-01-01 00:00:00'), 0.9637117377995325, 7,
        'seven'],
       [18L, Timestamp('2017-01-01 00:00:00'), 0.7547980447750812, 8,
        'eight'],
       [19L, Timestamp('2017-01-01 00:00:00'), 0.1840863987352963, 9,
        'nine']], dtype=object)
df2.describe()
A C D
count 9.000000 9.000000 9.000000
mean 15.000000 0.663296 5.000000
std 2.738613 0.332958 2.738613
min 11.000000 0.115527 1.000000
25% 13.000000 0.512081 3.000000
50% 15.000000 0.754798 5.000000
75% 17.000000 0.963712 7.000000
max 19.000000 0.986166 9.000000
df2.T
11 12 13 14 15 16 17 18 19
A 11 12 13 14 15 16 17 18 19
B 2017-01-01 00:00:00 2017-01-01 00:00:00 2017-01-01 00:00:00 2017-01-01 00:00:00 2017-01-01 00:00:00 2017-01-01 00:00:00 2017-01-01 00:00:00 2017-01-01 00:00:00 2017-01-01 00:00:00
C 0.115527 0.966706 0.627952 0.858634 0.512081 0.986166 0.963712 0.754798 0.184086
D 1 2 3 4 5 6 7 8 9
E one two three four five six seven eight nine
df2.sort_index(axis=1,ascending=False)
E D C B A
11 one 1 0.115527 2017-01-01 11
12 two 2 0.966706 2017-01-01 12
13 three 3 0.627952 2017-01-01 13
14 four 4 0.858634 2017-01-01 14
15 five 5 0.512081 2017-01-01 15
16 six 6 0.986166 2017-01-01 16
17 seven 7 0.963712 2017-01-01 17
18 eight 8 0.754798 2017-01-01 18
19 nine 9 0.184086 2017-01-01 19
df2.sort_values(by="C")
A B C D E
11 11 2017-01-01 0.115527 1 one
19 19 2017-01-01 0.184086 9 nine
15 15 2017-01-01 0.512081 5 five
13 13 2017-01-01 0.627952 3 three
18 18 2017-01-01 0.754798 8 eight
14 14 2017-01-01 0.858634 4 four
17 17 2017-01-01 0.963712 7 seven
12 12 2017-01-01 0.966706 2 two
16 16 2017-01-01 0.986166 6 six

通过标签选择

loc与at相似,但是at只能选取一个值,而loc可以选取行或列

df2.loc[11]
A                     11
B    2017-01-01 00:00:00
C               0.115527
D                      1
E                    one
Name: 11, dtype: object
df2.loc[:,["A","B"]]
A B
11 11 2017-01-01
12 12 2017-01-01
13 13 2017-01-01
14 14 2017-01-01
15 15 2017-01-01
16 16 2017-01-01
17 17 2017-01-01
18 18 2017-01-01
19 19 2017-01-01
df2.loc[13,"C"]
0.62795150964677393

通过位置选择

df2.iloc[0]
A                     11
B    2017-01-01 00:00:00
C               0.115527
D                      1
E                    one
Name: 11, dtype: object
df2.iloc[:3,0:3]
A B C
11 11 2017-01-01 0.115527
12 12 2017-01-01 0.966706
13 13 2017-01-01 0.627952
df2.iloc[[1,3,5],[1,3]]
B D
12 2017-01-01 2
14 2017-01-01 4
16 2017-01-01 6
df2.iloc[1,2]
0.96670647721356373

布尔索引

df2[df2.C>0.5]
A B C D E
12 12 2017-01-01 0.966706 2 two
13 13 2017-01-01 0.627952 3 three
14 14 2017-01-01 0.858634 4 four
15 15 2017-01-01 0.512081 5 five
16 16 2017-01-01 0.986166 6 six
17 17 2017-01-01 0.963712 7 seven
18 18 2017-01-01 0.754798 8 eight
df1[ df1 > 0]
a b c d
2017-01-01 NaN 0.308452 1.550586 0.022510
2017-01-02 0.011909 NaN NaN NaN
2017-01-03 1.016461 NaN 1.399342 1.435456
2017-01-04 NaN NaN NaN 0.833718
2017-01-05 1.298400 NaN NaN 0.718973
2017-01-06 0.265090 0.490953 1.048929 NaN
2017-01-07 NaN 1.640064 NaN NaN
2017-01-08 NaN 0.541123 0.415082 0.368303
2017-01-09 0.352406 NaN 1.385387 0.240791
2017-01-10 NaN NaN 0.163297 NaN
2017-01-11 1.707390 1.000258 0.717216 NaN
2017-01-12 NaN 0.742661 NaN NaN
2017-01-13 NaN NaN NaN NaN
2017-01-14 0.285966 1.219942 1.679262 0.170911
2017-01-15 NaN NaN 1.827916 0.359999
2017-01-16 0.834599 0.214739 NaN 0.637817
2017-01-17 1.233904 NaN NaN 0.651542
2017-01-18 2.211547 1.652226 1.415402 NaN
2017-01-19 0.176992 0.228890 0.844449 1.267496
2017-01-20 NaN NaN 0.377210 0.521628
df2[df2['E'].isin(["one","six"])]
A B C D E
11 11 2017-01-01 0.115527 1 one
16 16 2017-01-01 0.986166 6 six
df2[df2.E.isin(['one',"six"])]
A B C D E
11 11 2017-01-01 0.115527 1 one
16 16 2017-01-01 0.986166 6 six
s1=pd.Series([111,22,33,44],index=range(12,16))
df2["F"]=s1
df2
A B C D E F
11 11 2017-01-01 0.115527 1 one NaN
12 12 2017-01-01 0.966706 2 two 111.0
13 13 2017-01-01 0.627952 3 three 22.0
14 14 2017-01-01 0.858634 4 four 33.0
15 15 2017-01-01 0.512081 5 five 44.0
16 16 2017-01-01 0.986166 6 six NaN
17 17 2017-01-01 0.963712 7 seven NaN
18 18 2017-01-01 0.754798 8 eight NaN
19 19 2017-01-01 0.184086 9 nine NaN
df2.at[17,"D"]=3
print df2
df2.iat[1,0]=1
print df2
print len(df2)
df2['F']=np.array([5]*len(df2))
print df2
     A          B         C  D      E      F
11  11 2017-01-01  0.115527  1    one    NaN
12  12 2017-01-01  0.966706  2    two  111.0
13  13 2017-01-01  0.627952  3  three   22.0
14  14 2017-01-01  0.858634  4   four   33.0
15  15 2017-01-01  0.512081  5   five   44.0
16  16 2017-01-01  0.986166  6    six    NaN
17  17 2017-01-01  0.963712  3  seven    NaN
18  18 2017-01-01  0.754798  8  eight    NaN
19  19 2017-01-01  0.184086  9   nine    NaN
     A          B         C  D      E      F
11  11 2017-01-01  0.115527  1    one    NaN
12   1 2017-01-01  0.966706  2    two  111.0
13  13 2017-01-01  0.627952  3  three   22.0
14  14 2017-01-01  0.858634  4   four   33.0
15  15 2017-01-01  0.512081  5   five   44.0
16  16 2017-01-01  0.986166  6    six    NaN
17  17 2017-01-01  0.963712  3  seven    NaN
18  18 2017-01-01  0.754798  8  eight    NaN
19  19 2017-01-01  0.184086  9   nine    NaN
9
     A          B         C  D      E  F
11  11 2017-01-01  0.115527  1    one  5
12   1 2017-01-01  0.966706  2    two  5
13  13 2017-01-01  0.627952  3  three  5
14  14 2017-01-01  0.858634  4   four  5
15  15 2017-01-01  0.512081  5   five  5
16  16 2017-01-01  0.986166  6    six  5
17  17 2017-01-01  0.963712  3  seven  5
18  18 2017-01-01  0.754798  8  eight  5
19  19 2017-01-01  0.184086  9   nine  5
df3=df2.copy()
df3["B"]=df3["E"]=6
df3[df3>0]=-df3
print df3
df3.iloc[1:3,1:3]=np.nan
print df3.isnull()
print np.isnan(df3.iloc[1,1])
     A  B         C  D  E  F
11 -11 -6 -0.115527 -1 -6 -5
12  -1 -6 -0.966706 -2 -6 -5
13 -13 -6 -0.627952 -3 -6 -5
14 -14 -6 -0.858634 -4 -6 -5
15 -15 -6 -0.512081 -5 -6 -5
16 -16 -6 -0.986166 -6 -6 -5
17 -17 -6 -0.963712 -3 -6 -5
18 -18 -6 -0.754798 -8 -6 -5
19 -19 -6 -0.184086 -9 -6 -5
        A      B      C      D      E      F
11  False  False  False  False  False  False
12  False   True   True  False  False  False
13  False   True   True  False  False  False
14  False  False  False  False  False  False
15  False  False  False  False  False  False
16  False  False  False  False  False  False
17  False  False  False  False  False  False
18  False  False  False  False  False  False
19  False  False  False  False  False  False
True

reindex() 方法可以对指定轴上的索引进行改变/增加/删除操作,这将返回原始数据的一个拷贝

dates=pd.date_range("20170101",periods=len(df2))
print df2
df4=df2.reindex(index=dates,columns=list(df2.columns))
print df4
     A          B         C  D      E  F
11  11 2017-01-01  0.115527  1    one  5
12   1 2017-01-01  0.966706  2    two  5
13  13 2017-01-01  0.627952  3  three  5
14  14 2017-01-01  0.858634  4   four  5
15  15 2017-01-01  0.512081  5   five  5
16  16 2017-01-01  0.986166  6    six  5
17  17 2017-01-01  0.963712  3  seven  5
18  18 2017-01-01  0.754798  8  eight  5
19  19 2017-01-01  0.184086  9   nine  5
             A   B   C   D    E   F
2017-01-01 NaN NaT NaN NaN  NaN NaN
2017-01-02 NaN NaT NaN NaN  NaN NaN
2017-01-03 NaN NaT NaN NaN  NaN NaN
2017-01-04 NaN NaT NaN NaN  NaN NaN
2017-01-05 NaN NaT NaN NaN  NaN NaN
2017-01-06 NaN NaT NaN NaN  NaN NaN
2017-01-07 NaN NaT NaN NaN  NaN NaN
2017-01-08 NaN NaT NaN NaN  NaN NaN
2017-01-09 NaN NaT NaN NaN  NaN NaN
df5=df2.reindex(index=range(14,18),columns=list(df2.columns)+["G"])
print df5
     A          B         C  D      E  F   G
14  14 2017-01-01  0.858634  4   four  5 NaN
15  15 2017-01-01  0.512081  5   five  5 NaN
16  16 2017-01-01  0.986166  6    six  5 NaN
17  17 2017-01-01  0.963712  3  seven  5 NaN
df5.loc[14,"C"]=np.nan
print df5
df5=df5.reindex(columns=list(np.array(["A","B","C","D"])))
print df5
df6=df5.dropna(how="any")
print df5
print df6
df7=df5.fillna(value=1111)
print df7
     A          B         C  D      E  F   G
14  14 2017-01-01       NaN  4   four  5 NaN
15  15 2017-01-01  0.512081  5   five  5 NaN
16  16 2017-01-01  0.986166  6    six  5 NaN
17  17 2017-01-01  0.963712  3  seven  5 NaN
     A          B         C  D
14  14 2017-01-01       NaN  4
15  15 2017-01-01  0.512081  5
16  16 2017-01-01  0.986166  6
17  17 2017-01-01  0.963712  3
     A          B         C  D
14  14 2017-01-01       NaN  4
15  15 2017-01-01  0.512081  5
16  16 2017-01-01  0.986166  6
17  17 2017-01-01  0.963712  3
     A          B         C  D
15  15 2017-01-01  0.512081  5
16  16 2017-01-01  0.986166  6
17  17 2017-01-01  0.963712  3
     A          B            C  D
14  14 2017-01-01  1111.000000  4
15  15 2017-01-01     0.512081  5
16  16 2017-01-01     0.986166  6
17  17 2017-01-01     0.963712  3

相关操作

print df7.mean()
A     15.50000
C    278.36549
D      4.50000
dtype: float64
print df7.mean(1)
14    376.333333
15      6.837360
16      7.662055
17      6.987904
dtype: float64
dates=pd.date_range("2017-01-01",periods=4)
print dates
s2=pd.Series(range(0,len(dates)),index=dates).shift(2)
print s2
DatetimeIndex(['2017-01-01', '2017-01-02', '2017-01-03', '2017-01-04'], dtype='datetime64[ns]', freq='D')
2017-01-01    NaN
2017-01-02    NaN
2017-01-03    0.0
2017-01-04    1.0
Freq: D, dtype: float64
#sub Equivalent to dataframe - other, but with support to substitute a fill_value for missing data 
#in one of the inputs.
dates=pd.date_range("2017-01-01",periods=4)
df7=df7.set_index(dates)
df7.iloc[3,0]=np.nan
df7.iloc[2,2]=np.nan
df7["F"]=np.nan
df7["B"]=13
print df7
df7=df7.sub(s2,axis="index")
print df7
               A   B            C  D   F
2017-01-01  14.0  13  1111.000000  4 NaN
2017-01-02  15.0  13     0.512081  5 NaN
2017-01-03  16.0  13          NaN  6 NaN
2017-01-04   NaN  13     0.963712  3 NaN
               A     B         C    D   F
2017-01-01   NaN   NaN       NaN  NaN NaN
2017-01-02   NaN   NaN       NaN  NaN NaN
2017-01-03  16.0  13.0       NaN  6.0 NaN
2017-01-04   NaN  12.0 -0.036288  2.0 NaN
a = np.array([[11,24,37], [41,51,61]])
print a
print np.cumsum(a)
print np.cumsum(a,axis=0)
print np.cumsum(a,axis=1)
[[11 24 37]
 [41 51 61]]
[ 11  35  72 113 164 225]
[[11 24 37]
 [52 75 98]]
[[ 11  35  72]
 [ 41  92 153]]
print df1
df1.apply(np.cumsum)
                   a         b         c         d
2017-01-01 -0.731296  0.308452  1.550586  0.022510
2017-01-02  0.011909 -2.604560 -0.328210 -0.831059
2017-01-03  1.016461 -0.340761  1.399342  1.435456
2017-01-04 -0.610496 -0.962359 -0.397980  0.833718
2017-01-05  1.298400 -0.148515 -1.366670  0.718973
2017-01-06  0.265090  0.490953  1.048929 -0.611945
2017-01-07 -0.718811  1.640064 -1.063297 -1.092510
2017-01-08 -0.686471  0.541123  0.415082  0.368303
2017-01-09  0.352406 -0.061781  1.385387  0.240791
2017-01-10 -0.750252 -0.353765  0.163297 -0.706397
2017-01-11  1.707390  1.000258  0.717216 -0.566941
2017-01-12 -0.341289  0.742661 -1.820184 -0.182327
2017-01-13 -0.583300 -0.490837 -0.611798 -1.238514
2017-01-14  0.285966  1.219942  1.679262  0.170911
2017-01-15 -0.100615 -0.111391  1.827916  0.359999
2017-01-16  0.834599  0.214739 -0.868497  0.637817
2017-01-17  1.233904 -0.296525 -0.218316  0.651542
2017-01-18  2.211547  1.652226  1.415402 -1.023644
2017-01-19  0.176992  0.228890  0.844449  1.267496
2017-01-20 -0.242708 -0.792746  0.377210  0.521628
a b c d
2017-01-01 -0.731296 0.308452 1.550586 0.022510
2017-01-02 -0.719387 -2.296108 1.222376 -0.808550
2017-01-03 0.297075 -2.636869 2.621718 0.626906
2017-01-04 -0.313422 -3.599228 2.223738 1.460624
2017-01-05 0.984978 -3.747743 0.857069 2.179597
2017-01-06 1.250069 -3.256790 1.905998 1.567652
2017-01-07 0.531258 -1.616726 0.842700 0.475142
2017-01-08 -0.155213 -1.075604 1.257782 0.843444
2017-01-09 0.197193 -1.137385 2.643169 1.084235
2017-01-10 -0.553059 -1.491150 2.806466 0.377838
2017-01-11 1.154331 -0.490892 3.523682 -0.189103
2017-01-12 0.813042 0.251769 1.703498 -0.371430
2017-01-13 0.229742 -0.239067 1.091700 -1.609944
2017-01-14 0.515708 0.980875 2.770962 -1.439033
2017-01-15 0.415093 0.869484 4.598878 -1.079034
2017-01-16 1.249693 1.084223 3.730380 -0.441217
2017-01-17 2.483597 0.787698 3.512064 0.210325
2017-01-18 4.695144 2.439923 4.927466 -0.813319
2017-01-19 4.872136 2.668814 5.771915 0.454177
2017-01-20 4.629428 1.876068 6.149125 0.975805
df1.apply(lambda x:x.max()-x.min())
a    2.961799
b    4.256786
c    3.648100
d    2.673969
dtype: float64
s3=pd.Series(np.random.randint(0,7,size=10))
print s3
#Returns object containing counts of unique values.
s3.value_counts()
0    1
1    3
2    3
3    3
4    4
5    4
6    5
7    0
8    6
9    1
dtype: int32





3    3
4    2
1    2
6    1
5    1
0    1
dtype: int64
s=pd.Series(['A', 'B', 'C', 'Aaba', 'Baca', np.nan, 'CABA', 'dog', 'cat'])
s
0       A
1       B
2       C
3    Aaba
4    Baca
5     NaN
6    CABA
7     dog
8     cat
dtype: object
s.str.upper()
0       A
1       B
2       C
3    AABA
4    BACA
5     NaN
6    CABA
7     DOG
8     CAT
dtype: object
df1=pd.DataFrame(np.random.randn(10,4))
df1
0 1 2 3
0 -0.932914 -1.888419 0.382424 -0.818447
1 0.610921 1.115466 -0.198243 0.729085
2 0.000842 -1.159236 0.979033 0.375346
3 -0.634415 -0.204233 2.395083 -0.647589
4 -1.354108 -0.278728 1.042867 1.286785
5 0.914505 -0.664796 1.112920 -0.094563
6 -0.167151 -1.519254 0.015029 -0.567899
7 -0.225384 -0.293270 0.209918 -0.205145
8 0.562184 -0.706002 -0.786689 0.780558
9 -0.075450 -0.983625 -0.053178 -1.989312
#concat 合并
pieces=[df1[:3],df1[:3]]
pd.concat(pieces)
0 1 2 3
0 -0.932914 -1.888419 0.382424 -0.818447
1 0.610921 1.115466 -0.198243 0.729085
2 0.000842 -1.159236 0.979033 0.375346
0 -0.932914 -1.888419 0.382424 -0.818447
1 0.610921 1.115466 -0.198243 0.729085
2 0.000842 -1.159236 0.979033 0.375346
left = pd.DataFrame({'key': ['foo', 'bar'], 'lval': [1,2]})
right = pd.DataFrame({'key': ['foo', 'bar'], 'rval': [4,5]})
left
key lval
0 foo 1
1 bar 2
right
key rval
0 foo 4
1 bar 5
pd.merge(left,right,on="key")
key lval rval
0 foo 1 4
1 bar 2 5
df1
0 1 2 3
0 -0.932914 -1.888419 0.382424 -0.818447
1 0.610921 1.115466 -0.198243 0.729085
2 0.000842 -1.159236 0.979033 0.375346
3 -0.634415 -0.204233 2.395083 -0.647589
4 -1.354108 -0.278728 1.042867 1.286785
5 0.914505 -0.664796 1.112920 -0.094563
6 -0.167151 -1.519254 0.015029 -0.567899
7 -0.225384 -0.293270 0.209918 -0.205145
8 0.562184 -0.706002 -0.786689 0.780558
9 -0.075450 -0.983625 -0.053178 -1.989312
left.append(right,ignore_index=True)
key lval rval
0 foo 1.0 NaN
1 bar 2.0 NaN
2 foo NaN 4.0
3 bar NaN 5.0
df1=pd.DataFrame({"A":["one","two","one","two","one","two","one","two"],"B":np.random.randn(8),"C":[3,4,5,2,1,2,1,2]})
df1.groupby("A").sum()
B C
A
one 1.358529 10
two 0.522721 10
df1.groupby(["A","C"]).sum()
B
A C
one 1 0.249465
3 -0.328484
5 1.437548
two 2 -0.171024
4 0.693745
df1=pd.DataFrame(np.random.randn(1000,4),index=pd.date_range("20170101",periods=1000),columns=["A","B","C","D"])
df1=df1.cumsum()
df1.plot()

df1=df1.cumsum()
df1.plot()

字符串翻转算法

#ifndef XINWEI_ROTATESTRING_H_
#define XINWEI_ROTATESTRING_H_
#include <iostream>

using namespace std;
void ReverseString(char *s,int from , int to){
    char temp;
    while (from <to){
        temp=*(s+from);
        *(s+from)=*(s+to);
        *(s+to)=temp;
        from++;
        to--;
    }
}
void LeftShiftOne(char* s,int n){
    char temp=s[0];
    int i=0;
    while (i<n-1){
        s[i]=s[i+1];
        i++;
    }
    s[n-1]=temp;
}
/**
 * (X^TY^T)^T=YX
 * n字符串长度,m旋转前m位
 */
void LeftRotateString(char* s,int n,int m){
    ReverseString(s,0,m-1);
    ReverseString(s,m,n-1);
    ReverseString(s,0,n-1);
}
void LeftRotateString2(char* s,int n,int m){
    while (m--){
        LeftShiftOne(s,n);
    }
}
void RightRotateString(char* s,int n,int m){
    ReverseString(s,0,n-m-1);
    ReverseString(s,n-m,n-1);
    ReverseString(s,0,n-1);
}
void ReverseWords(char* s){
    ReverseString(s,0,strlen(s)-1);
    int x=0;
    for (int j = 0; j <strlen(s) ; ++j) {
        if(s[j]==' '){
            ReverseString(s,x,j-1);
            x=j+1;
        }
    }
}

#endif

字符串字母包含算法


给定两个分别由字母组成的字符串A和字符串B,字符串B的长度比字符串A短。请问,如何最快地判断字符串B中所有字母是否都在字符串A里?为了简单起见,我们规定输入的字符串只包含大写英文字母,请实现函数
bool StringContains(string &A, string &B)


// Created by Lv,Xinwei on 2018/2/5.
/**
 * 穷举查找O(nm)
 * @param A
 * @param B
 * @return
 */
bool StringContains(string &A, string &B) {
    typedef string::const_iterator it;
    int num=0;
    for (it i = B.begin(); i < B.end(); i++) {
        for (it j = A.begin(); j < A.end(); j++) {
            if (*i == *j) {
                num++;
                break;
            }
        }
    }
    return num==B.length();
}
int  cmp(const void* a,const void*  b){
    return ( *(char*)a - *(char*)b );
}
/**
 * 排序查找O(nlogN+mlogM+m)
 * @param A
 * @param B
 * @return
 */
bool StringContains2(string &A, string &B) {
    sort(A.begin(),A.end());
    sort(B.begin(),B.end());
    typedef string::const_iterator it;
    it j=A.begin();
    for (it i = B.begin(); i < B.end(); i++) {
        for (; j < A.end(); ) {
            if (*i == *j) {
                break;
            }
            j++;
        }
        if(j==A.end()){
            return false;
        }
    }
    return true;
}
/**
 * 使用map O(n+m)
 * @param A
 * @param B
 * @return
 */
bool StringContains3(string &A, string &B) {
    map<int,char> bulk;
    typedef string::const_iterator it;
    for (it i = A.begin();  i<A.end() ; i++) {
        bulk.insert(pair<char,int>(*i,1));
    }
    for (it i = B.begin();  i<B.end() ; i++) {
        if(bulk.find(*i)==bulk.end()){
            return false;
        }
    }
    return true;
}
/**
 * 使用位计算 O(n+m)
 * @param A
 * @param B
 * @return
 */
bool StringContains4(string &A, string &B) {
    int bit_counter=0;
    typedef string::const_iterator it;
    for (it i = A.begin(); i <A.end() ; i++) {
        bit_counter|=1<<((*i)-'a');
    }
    for (it i = B.begin(); i <B.end() ; i++) {
        if((bit_counter&(1<<((*i)-'a')))==0){
            return false;
        }
    }
    return true;
}
void testStringContain(){
    string s1="aafgrsdf fsefvdgdfhfg";
    string s2="absdff afsvxcvasdfc";
    cout<<StringContains(s1,s2)<<endl;
    s1="aafgrsdfsdfscde";
    s2="absdffsdafsddafqwdfc";
    cout<<StringContains2(s1,s2)<<endl;
    cout<<s1<<endl;
    map<char,int> bulk;
    typedef map<char,int>::const_iterator it;
    pair<char,int> data('s',11);
    bulk.insert(data);
    data={'s',100};
    pair<it,bool> temp=bulk.insert(data);
    cout <<temp.second<<endl;
    it iii=temp.first;
    cout <<iii->first<<iii->second<<endl;
    s1="aafsdfsdawefscde";
    s2="ab";
    cout<<StringContains3(s1,s2)<<endl;
    s1="aafgrsdefwfgjuytnwabcde";
    s2="abgfex";
    cout<<StringContains4(s1,s2)<<endl;
}
#endif //THEARTOFPROGRAMING_STRINGCONTAIN_H

最长回文串算法

给定一个字符串,求它的最长回文子串的长度。

/**
 * @param s 
 * @param n 
 * @return 
 */
bool IsPalindrome(const char *s, int n){
    if(s== NULL||n<1){
        return false;
    }
    for (int i = 0; i < n/2; ++i) {
        if(s[i]!=s[n-i-1]){
            return false;
        }
    }
    return true;
}/**
 * 穷举法遍历所有长度 O(n^3)
 * @param s
 * @param n
 * @return
 */
int LongestPalindrome(const char *s, int n){
    if(s== nullptr||n<1){
        return 0;
    }
    int longest=0;
    for(int i=1;i<=n;i++){
        for(int j=0;j<=n-i;j++){
            if(IsPalindrome(s+j,i)){
                longest=longest<i?i:longest;
            }
        }
    }
    return longest;
}
/**
 * 找中心点向外扩散 O(n^2)
 * @param s
 * @param n
 * @return
 */
int LongestPalindrome2(const char *s, int n){
    if(s== nullptr||n<1){
        return 0;
    }
    int longest=0;//长度
    //i是中心点下标
    for (int i = 0; i <n ; ++i) {
        //j是长度
        //奇数串
        for (int j = 0;(i-j)>=0&&(i+j)<n; ++j) {
            if(s[i-j]!=s[i+j]){
                break;
            }
            int c=j*2+1;
            longest=longest<c?c:longest;
        }
        for (int j = 0;(i-j)>=0&&(i+j+1)<n; ++j) {
            if(s[i-j]!=s[i+j+1]){
                break;
            }
            int c=j*2+2;
            longest=longest<c?c:longest;
        }
    }
    return longest;

}
/**
 * Manacher算法 O(n)
 * @param s
 * @param n
 * @return
 */
int LongestPalindrome3(const char *s, int n){
    if(s== nullptr||n<1){
        return 0;
    }
    char str[n*2+4];
    int j=0;
    str[j++]='$';
    str[j++]='#';

    for (int i = 0; i < n; ++i) {
        //使回文串长度变成偶数
        str[j++]=*(s+i);
        str[j++]='#';
    }
    str[j]='\0';
    int p[j-1];//保存以下标为中心点的最长回文串长度
    memset(p,0, sizeof(p));
    int mx=0;//回文串最右边界
    int idx=0;//回文串中心点
    int longest=0;//最长子串
    for(int i=1;i<j-1;i++){
        p[i]=mx>i?min(mx-i,p[2*idx-i]):1;//2*idx-i 与i关于idx对称,如果p[2*idx-i]比mx-i长则说明p[i]>=p[2*idx-i] 短的话 p[i]=p[2*idx-i]
        while(str[i-p[i]]==str[i+p[i]]){
            p[i]++; //继续求p[i]的最长回文串
        }
        longest=p[i]>longest?p[i]:longest;
        if(p[i]+i>mx){
            mx=p[i]+i;
            idx=i;
        }
    }
    return longest-1;
} 

squid 配置HTTPS代理

从源代码编译:(编译的squid必须是3.3或以上的版本。2.x版好像没有加密代理功能)

 yum install openssl openssl-devel  gcc-c++ bzip2 gcc perl

(如果你的系统是DEBIAN/UBUNTU,则需运行命令:

apt-get install openssl libssl-dev gcc g++ bzip2 perl

否则编译时,会遇到错误提示:configure: error: library ‘crypto’ is required for OpenSSL。参见
http://superuser.com/questions/371901/openssl-missing-during-configure-how-to-fix)

wget http://www.squid-cache.org/Versions/v3/3.5/squid-3.5.7.tar.bz2
tar jxvf squid-3.5.7.tar.bz2
cd squid-3.5.7
./configure --prefix=/usr --sysconfdir=/etc/squid --libdir=/usr/lib --with-openssl
--enable-basic-auth-helpers="LDAP,MSNT,NCSA,PAM,SASL,SMB,YP,DB,POP3,getpwnam,squid_radius_auth,multi-domain-NTLM" --with-swapdir=/var/spool/squid --libexecdir=/usr/lib/squid
make (此步骤耗时15分钟)
make install

配置squid,(修改SQUID的配置文件squid.conf)
然后修改Squid的配置文件。把http_port变成https_port ,修改监听的端口号为443:

https_port 443 cert=/etc/squid/public.crt key=/etc/squid/private.key

其中cert和key分别是网站的HTTPS证书和私钥。在/etc/squid/目录中,运行openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout private.key -out public.crt即可生成public.crt和private.key 。注意:监听的端口号必须设为443.否则squid启动不了。
chrome支持https类型的代理。启动chrome的时候在末尾加上–proxy-server=https://vps-ip:443 –ignore-certificate-errors即可。注意,把这里的vps-ip换成你的服务器的ip。
全配置好之后,用chrome浏览器即可翻墙。

证书可以用商业证书,自己生成的比较麻烦。。

启用用户认证了。

具体方法如下:yum install httpd (debian/ubuntu系统下,则apt-get install apache2)这样你的系统上就会出现htpasswd命令。然后在/etc/squid/目录里,运行htpasswd -cb /etc/squid/users jones fx5rm31s上述命令将生成密码文件users.(jones和fx5rm31s分别为你指定的用户名和密码)然后,编辑/etc/squid/squid.conf文件,在http_access deny all那一段的上方,插入:

auth_param basic program /usr/lib/squid/basic_ncsa_auth /etc/squid/users
auth_param basic children 5
auth_param basic realm Squid proxy-caching web server
auth_param basic credentialsttl 2 hours
acl normal proxy_auth REQUIRED
http_access allow normal
auth_param basic casesensitive off

然后重启squid,即可启用squid的认证机制。

随便聊聊

又好久没更新了,随便聊聊吧。
随着媳妇产期来临,开始慢慢接受当爹了这个事实,挺好的,为人父就要做出表率,控制好自己的情绪,照顾好家人。
最近搞了烘培,挺有意思的,发现比面食简单多了,只要按照固定的比例做就行了,味道都还不错,做面食影响的因素就太多了。
最近对交易有了更深入的理解,换句话说对人性更加理解了,在这个地方捡块肉是件很不容易的事,忠于自己的内心,控制好风险,分散仓位。
最近两年错失了几个机会,希望后面可以更加努力,改变命运。
突然不想喝酒了,一辈子很短,好好珍惜。

前端接口防刷方法探究

暴露在前端的接口被刷是件很头疼的事,这件事情无解,根据我观察,目前主流有三种方法:
1. 通过Js注入Cookie数据,此Cookie数据会在后端进行校检,此种方式必须采用渲染Js来进行破解,提高了刷接口成本。
2. 在前端对请求参数进行加密,加密方法采用代码混淆技术,这种成本比较低,效果还不错。
3. 每次请求生成一个唯一字符串,把该字符串注入Cookie中,此串只能用一次,当访问接口时会校检该串是否有效或是否被用过,无效串直接403。
出于成本考虑我采用1和2两种方法的结合,具体流程如下:
1. 生成一个与时间戳有关系的字符串K,该字符串可采用Rc4加密算法生成,保证加密串可以被还原成时间戳。
2. 将K注入Cookie中
3. 前端拿到K,根据请求参数算出Sign
4. 前端把Sign和请求参数传递到后端,后端首先提取出K计算是否有效、是否过期了一定时间间隔,然后计算Sign是否有效

/**
     * 获取与时间戳有关的加密串
     * @Return String
     */
    Public Static Function Getencryptionkey() {
        $Timestamp = Strval(Time());
        $Rc4ret = Self::Rc4(Self::Common_secret_key, $Timestamp);
        Return Base64_encode($Rc4ret);
    }

    /**
     * 从加密串中解出时间戳
     * @Param $Key
     * @Return String
     */
    Public Static Function Decodeencryptionkey($Key) {
        Return Self::Rc4(Self::Common_secret_key, Base64_decode($Key));
    }

    /**
     * 验证加密串是否有效,考虑时间戳的失效时间。
     * @Param $Key
     * @Return Bool
     */
    Public Static Function Checkencryptionkey($Key) {
        $Nowtimestamp = Intval(Time());
        If (!Empty($Key)) {
            $Encyptiontimestamp = Intval(Self::Decodeencryptionkey($Key));
            Return (($Encyptiontimestamp + Self::Max_valid_time_interval) >= $Nowtimestamp);
        }
        Return False;
    }

git rebase

简介

在Git中,用两种方法将两个不同的branch合并。一种是通过git merge,一种是通过git rebase。然而,大部分人都习惯于使用git merge,而忽略git rebase。本文将介绍git rebase的原理、使用方式及应用范围。

git merge 做些什么

当我们在开发一些新功能的时候,往往需要建立新的branch。

在上图中,每一个绿框均代表一个commit。除了c1,每一个commit都有一条有向边指向它在当前branch当中的上一个commit。

图中的项目,在c2之后就开了另外一个branch,名为experiment。在此之后,master下的修改被放到c4 commit中,experiment下的修改被放到c3 commit中。

如果我们使用merge合并两个分支
$ git checkout master
$ git merge experiment

得到的commit log如下图所示

我们看到,merge所做的事情实际上是:

  1. 首先找到masterexperiment中最新的commit的最近公共祖先,在这里就是c4c3的最近公共祖先c2
  2. experiment分支上在c2以后的所有commit合并成一个commit,并与master合并
  3. 如有合并冲突(两个分支修改了同一个文件),首先人工去除重复。
  4. 在master上产生合并后的新commit

git rebase做些什么

rebase所做的事情也是合并两个分支,但是它的方式略有不同。基于上例描述,rebase的工作流程是

  1. 首先找到masterexperiment中最新的commit的最近公共祖先,在这里就是c4c3的最近公共祖先c2
  2. experiment分支上在c2以后的所有commit*全部移动到*master分支的最新commit之后,在这里就是把c3移动到c4以后。

由于git的每一个commit都只存储相对上一个commit的变化(或者说是差值,delta)。我们通过移动c3到master,代表着在master上进行c3相应的修改。为了达成这一点,只需在experiment分支上rebase master
$ git checkout experiment
$ git rebase master

需要注意的是,rebase并不是直接将c3移动到master上,而是创建一个副本。我们可以通过实际操作发现这一点。在rebase前后,c3的hash code是不一样的。

rebase前的commit log是
* 1b4c6d6 (master) <- c4
| * 66c417b (experiment) <- c3
|/
* 972628d

rebase后的commit log是
* d9eeb1a - (experiment) <- c3'
* 1b4c6d6 - (master) <- c4
* 972628d

可以发现c3的hash code从66c417b变到了d9eeb1a

在这之后,我们只需要在master上进行一次前向合并(fast-forward merge)
$ git checkout master
$ git merge experiment

rebase之后的commit log呈线性,更加清晰。此时如果experiment分支不再被需要,我们可以删除它。
$ git branch -d experiment

何时使用

我们一般只在本地开发的时候rebase一个自己写出来的branch。

谨记,千万不要rebase一个已经发布到远程git服务器的分支。例如,你如果将分支experiment发布到了GitHub,那么你就不应该将它rebasemaster上。因为如果你将它rebasemaster上,将对其他人造成麻烦。

总结

git rebase帮助我们避免merge带来的复杂commit log,允许以线性commit的形式进行分支开发。