0%

Python用法小结

记录在2020年春项目中使用到的Python用法,包括统计检验和数据处理等方面。

统计检验相关

计算unpaired $t$ Test

给定两组array,利用stats库中的ttest_ind可以直接计算出$t$值和$p$ value。

1
2
stats.ttest_ind(array_a, array_b)
# > Ttest_indResult(statistic=0.096, pvalue=0.923)

也可以根据unpaired $t$ test的计算公式手动计算$t$值,其中$m_X$为array_X的平均值。
$$ t = \frac{m_A - m_B}{\sqrt{\frac{S^2}{n_A} + \frac{S^2}{n_B}}}$$
$$
S^2 = \frac{\sum(x-m_A)^2 + \sum(x-m_B)^2}{n_A + n_B - 2}
$$
代码如下:

1
2
3
4
5
6
7
8
9
10
11
a = 0
b = 0
n = len(array_A) # 设数组长度相同
for each in array_A:
a += (each-sum(array_A)/n)**2
for each in array_B:
b += (each-sum(array_B)/n)**2

s2 = (a+b) / (n*2-2)

t = (sum(array_A)/n - sum(array_B)/n) / ((s2/n+s2/n) ** 0.5)

计算Kendall’s $\tau_b$ value

Kendall’s $\tau$相关性系数测量的是两组数值在组内顺序上的相似性,分布于$[-1,1]$,其中,-1表示两组值完全逆序,比如[1,2,3,4][4,3,2,1]0表示两组排序结果无关;1表示两组顺序完全相同。
https://docs.scipy.org/doc/scipy-0.15.1/reference/generated/scipy.stats.kendalltau.html

1
2
# 这里计算的是$tau_b$
tau, p = stats.kendalltau(array_1, array_2)

计算标准差

使用numpy.std()可以直接计算数据的标准差,但是在使用的时候需要注意,numpy中需要手动设置自由度。

ddof : int, optional
Means Delta Degrees of Freedom. The divisor used in calculations is N - ddof, where N represents the number of elements. By default ddof is zero.

ddof=0时,计算的是总体标准差;在ddof=1时,计算的是样本标准差。在这个项目中需要计算的时样本标准差,所以需要显式地设置参数ddof=1

将dict保存为csv文件

Python csv中提供将Python字典保存为csv的方法,其中主要的参数包括:

  • f:文件
  • fieldnames:字段名,list
  • restval=’’:fieldnames中存在字典中不具有的key时填入的默认值
  • extrasaction=’raise’:当字典中的key不存在于fieldnames中时对应的操作,如果是raise,就会抛出ValueError;如果是ignore,那么这部分字段就会被忽略
1
2
3
4
5
6
7
8
9
10
csv_file = "file_name.csv"
csv_columns = [...] # set column names
try:
with open(csv_file, 'w', encoding="utf-8") as csvfile:
writer = csv.DictWriter(csvfile, fieldnames=csv_columns)
writer.writeheader()
for _data in data: #data为包含多个dict的数组
writer.writerow(_data)
except IOError:
print("I/O error")

Pandas用法总结

替换DataFrame列中字符串

1
data['A'] =data['A'].replace('old string', 'new string')

日期列的处理

1
data['Date'] = pd.to_datetime(data['Date'])

可以将字符串形式(object)的日期列转换为日期形式(datetime64[ns])。

1
data['Date'] = data['Date'].dt.strftime('%Y/%-m/%-d')

可以修改日期展示形式,这里的%-m中的-表示去除前导零,即2020/03/03将变为2020/3/3

得到满足对应列条件的行

1
2
data[(data.Date == '2020/3/3') & (data.Province == 'Shanghai') & (data.Country == 'China')]
# 得到数据中同时满足三个条件的行

过滤不满足条件的行,生成新df

1
2
3
condition = df.apply(lambda x: x.col1 == 0 and x.col2== 0 and x.col3==0, axis=1)

df_filter = df[~condition]

修改指定行中指定列的值

1
2
data.at[i,'column_name'] = 'new value'
# i为指定行的index

Pandas stack()

在处理数据的时候,需要对某一份数据做处理。原数据是以这样的方式存储的:

省份 2020/3/1 2020/3/2 20202/3/3
广东 2 2 2
上海 2 2 2
北京 2 2 2

希望修改为

日期 省份 人数
2020/3/1 广东 2
2020/3/1 上海 2
2020/3/1 北京 2
2020/3/2 广东 2
2020/3/2 上海 2
2020/3/2 北京 2
2020/3/3 广东 2
2020/3/3 上海 2
2020/3/3 北京 2

即将原来的每个数据作为以日期和省份为区别的一条记录。
最后使用了DataFrame中stack()来完成。

1
2
new_data = data.set_index('Province')
new_data = new_data.stack()

Dataframe的合并

这次项目中运用到了两种合并,一种是df之间关于列的拼接,一种是df关于行的拼接。

pandas merge()

merge()对应着数据库操作中的join()how参数提供了left, right, outer, inner(default)四种方式;on是指用于合并的label名或index(Column or index level names to join on.)

1
new_df = pd.merge(df_1, df_2, how='left', on=['col1','col2','col3'])

pandas append()

append()将两个df以行作合并,”Append rows of other to the end of caller, returning a new object.”

1
df_all = df_1.append(df_2)

合并Dataframe的行

有一个任务是要合并同一天同个国家所有省份的人数,利用groupby()来对数据进行分组,

1
new_df = df.groupby(["Date","Country"]).sum().reset_index()