Python还是要踏踏实实搞起来的
求两列时间相差的月份
data1 = data[['APP_ID']+list(data.columns[7:])].set_index('APP_ID').stack().reset_index()
data1.columns = ['APP_ID','payday','overdue']
data2 = data1.merge(data[['APP_ID','time1']],on = 'APP_ID')
#第一种方法:日期函数
import datetime
data2['time1'] = [datetime.datetime.strptime(str(i),'%Y%m') for i in data2['time1']]#time.strptime('2020-01-01','%Y-%m-%d')
data2['payday'] = [datetime.datetime.strptime(str(i),'%Y%m') for i in data2['payday']]
#求相差的月份
data2['month_diff'] = [(i.month+i.year*12)-(j.month+j.year*12) for i,j in zip(data2['payday'],data2['time1'])]
data2[:3]
#第二种方法:元组索引
import time
data2 = data1.merge(data[['APP_ID','time1']],on = 'APP_ID')
data2['time1'] = [time.strptime(str(i),'%Y%m')[:2] for i in data2['time1']]#time.strptime('2020-01-01','%Y-%m-%d')
data2['payday'] = [time.strptime(str(i),'%Y%m')[:2] for i in data2['payday']]
data2['month_diff'] = [(i[1]+i[0]*12)-(j[1]+j[0]*12) for i,j in zip(data2['payday'],data2['time1'])]
data2[:3]
#第三种方法:rrule
from dateutil import rrule
data2 = data1.merge(data[['APP_ID','time1']],on = 'APP_ID')
data2['payday'] = [datetime.datetime.strptime(str(i),'%Y%m') for i in data2['payday']]
data2['time1'] = [datetime.datetime.strptime(str(i),'%Y%m') for i in data2['time1']]
data2['delta'] = [rrule.rrule(rrule.MONTHLY, dtstart=d2, until=d1).count()-1 for (d1,d2) in zip(data2['payday'],data2['time1'])]
data2[:3]
原始数据与转换后格式:
显示所有行或列
import pandas as pd
#显示所有列
pd.set_option('display.max_columns', None)
#显示所有行
pd.set_options('display.max_rows', None)
#设置value的显示长度为100,默认为50
pd.set_option('max_colwidth',100)
random生成随机数,choice()和sample()不重复
生成随机矩阵(numpy random)
import numpy as np
>>> np.random.rand(4,3)
array([[ 0.06679473, 0.71073515, 0.5694172 ],
[ 0.95018143, 0.60161401, 0.8076899 ],
[ 0.40341822, 0.72154255, 0.92283012],
[ 0.81143322, 0.87853742, 0.38013707]])
np.random.randint(a, b, size=(c, d)):
>>> np.random.randint(0,10,(4,3))
array([[1, 9, 5],
[6, 1, 1],
[8, 2, 0],
[3, 4, 3]])
import random
print( random.randint(1,10) ) # 产生 1 到 10 的一个整数型随机数
print( random.random() ) # 产生 0 到 1 之间的随机浮点数
print( random.uniform(1.1,5.4) ) # 产生 1.1 到 5.4 之间的随机浮点数,区间可以不是整数
print( random.choice('tomorrow') ) # 从序列中随机选取一个元素
random.choices(range(1,34),k=6,weights=range(1,34))
print( random.randrange(1,100,2) ) # 生成从1到100的间隔为2的随机整数
random.sample(range(1,34),6)
#随机取1-33之间的6个随机数,不重复:
lists=[1,2,3,4,5,6]
lists2=[2,2,3,4,5,6]
for _ in range(2):
print (random.choice(lists))
for _ in range(3):
print (random.sample(lists,3))
1
4
[4, 2, 5]
[1, 2, 6]
[3, 2, 1]
shuffle() 函数
描述:shuffle() 方法将序列的所有元素随机排序。
注意:shuffle()是不能直接访问的,需要导入 random 模块,然后通过 random 静态对象调用该方法。
lst – 可以是一个序列或者元组。
import random
random.shuffle (lst )
--------------------------------
list = [20, 16, 10, 5];
random.shuffle(list)
print "随机排序列表 : ", list
--> 随机排序列表 : [16, 5, 10, 20]
any()和all()用法
any(x)
判断x对象是否为空对象,如果都为空、0、false,则返回false,如果不都为空、0、false,则返回true
all(x)
如果all(x)参数x对象的所有元素不为0、''、False或者x为空对象,则返回True,否则返回False
y.shape[0] 和 len(y)
y.shape 返回的一个元组,代表 y 数据集的信息如(行,列)
y.shape[0], 意思是:返回 y 中行的总数。
这个值在 y 是单特征的情况下 和 len(y) 是等价的
排序、分组、统计频次
SQL中的group by / order by
data.sort_values(by='列名',ascending=False).head()
# 按key1分组, 计算data1列的平均值
分组 = data.groupby(["key1"])["data1"].mean()
统计频次 = data['列名'].value_counts().reset_index()
--------------****SQL中的group by / order by ****
gp=df.groupby(by=['A','B','C'])#分组
newdf1=gp.size()#统计次数
newdf2 = newdf1.reset_index(name='times')#新列名
newdf2.sort_values(by = ['列名1','列名2'],ascending = (True,False))
--------------例:统计用户的每个设备的频率,排序
id_count1=login_table.groupby(by= ['cid','deviceId'])
id_count1.size().reset_index(name='times').sort_values(by = ['cid','times'],
ascending = (True,False)).head(10)
怎么对某一列截取
例如 ‘陕西省西安市’->‘西安市’
list切片知识点:
abc = ['文昌市','河北省']
abc[1][-2] ---> '北'
name_ = apply_table['mobileCity'].fillna('缺失') #有缺失会报错
new_name = []
for i in range(len(name_)):
if '省' in name_[i]:
pos_ = name_[i].find('省') #省份
new_name.append(name_[i][pos_+1:])
elif '区' in name_[i]: #自治区
pos_ = name_[i].find('区')
new_name.append(name_[i][pos_+1:])
else:
new_name.append(name_[i]) #直辖市
如何删除pandas DataFrame的某一/几列
方法一:直接del DF[‘column-name’]
方法二:采用drop方法,有下面三种等价的表达式:
- DF= DF.drop(‘column_name’, 1);
- DF.drop(‘column_name’,axis=1, inplace=True)
- DF.drop([DF.columns[[0,1, 3]]], axis=1,inplace=True) # Note: zero indexed
#inplace=True 原数组名对应的内存值直接改变
find()方法
Python find() 方法检测字符串中是否包含子字符串 str ,如果指定 beg(开始) 和 end(结束) 范围,则检查是否包含在指定范围内,如果包含子字符串返回开始的索引值,否则返回**-1**。
str.find(str, beg=0, end=len(string))
例
str1 = "this is string example....wow!!!";
str2 = "exam"
print str1.find(str2); ------- 15
print str1.find(str2, 10); ------- 15
print str1.find(str2, 40); ------- -1
.unique()
对于一维数组或列表,unique()按元素由小到大返回一个新的无元素重复的元组或者列表,
return_index=True表示返回新列表元素在旧列表中的位置,并以列表形式储存在s中
return_inverse=True 表示返回旧列表元素在新列表中的位置,并以列表形式储存在p中
a, s= np.unique(A, return_index=True)
a, s,p = np.unique(A, return_index=True, return_inverse=True)
r1=apply_table.groupby(['cid'])['mobile'].unique().reset_index()
若一个cid对应两个mobile,输出如下:
'cid1',['mobile1','mobile2']
'cid2',['mobile1']
疑问??
- shuffle
- df. columns={‘中级管理人员’, ‘实习生’, ‘普通员工’,‘高级管理人员’,‘abdc’}
命名列顺序会乱 - SQL的not in 在python怎么实现:循环??
待补充
pandas 计数value_counts()
pandas.Series.value_counts
Series.value_counts
(normalize=False, sort=True, ascending=False,
bins=None, dropna=True)
参数:
normalize : boolean, default False 如果设置为true,则以百分比的形式显示
sort : boolean, default True 是否排序
ascending : boolean, default False 默认降序排序
bins : integer, optional 而不是数值计算,把它们分成半开放的箱子,一个方便的pd.cut,只适用于数字数据
dropna : boolean, default True 默认删除na值
pandas之get_dummies() 0,1化(重要)
注意:主键是否重复
pandas.get_dummies(data, prefix=None, prefix_sep='_', #列名的前缀
dummy_na=False#增加一列表示空缺值,如果False就忽略空缺值
, columns=None, sparse=False , drop_first=False)
import pandas as pd
S = pd.Series(list('abcae'))
pd.get_dummies(S)
a b c e
0 1 0 0 0
1 0 1 0 0
2 0 0 1 0
3 1 0 0 0
4 0 0 0 1
命名&列之间运算生成新列并命名:lamda函数方法
df['result'] = df.apply(lambda x: x[1] / x[5], axis=1)
生成新列 df.eval() 方法 or 函数 df.apply(lambda x:)
pandas 实现对一行中的多个列运算生成新的列的方法,之前找了很久没找到,后来发现其实就是eval方法,非常好用。
inplace参数表示是否在原数据上操作inplace=False将会生成新的DataFrame
一次新增多个列可以使用
df.eval("""
.....: e = 气温 + 湿度
.....: f = 气温 - 湿度
.....: g = 气温 / 2.0""", inplace=True)
另:
df['Column'] = df.apply(lambda x: x[0] / x[1], axis=1)
命名&列之间运算生成新列并命名
df.rename()
df.columns =['column1','column2']
df.rename(index=str, columns={"A": "a", "B": "c"})
pandas使用drop_duplicates()去除DataFrame重复项
参数详解
data.drop_duplicates(subset=['A','B'],keep='first',inplace=True)
- subset对应的值是列名,表示只考虑这两列,将这两列对应值相同的行进行去重。默认值为subset=None表示考虑所有列.
2.keep=“first” /“last”/ False :False 去除所有重复行 - inplace=True / False : False副本,False时新增列会报错
where
Zcyl_d['Zcyl_d'] = np.where(Zcyl_d['mobile']==Zcyl_d['bankCardMobile'],1,0)
zip()
sorted()
>>> sorted([36, 5, -12, 9, -21], key=abs) #按绝对值排序
[5, 9, -12, -21, 36]
>>> sorted(['bob', 'about', 'Zoo', 'Credit'])
['Credit', 'Zoo', 'about', 'bob']#按照ASCII的大小比较'Z' < 'a'
>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True)
['Zoo', 'Credit', 'bob', 'about']
从上述例子可以看出,高阶函数的抽象能力是非常强大的,而且,核心代码可以保持得非常简洁。
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
from operator import itemgetter
print(sorted(L, key=itemgetter(0)))
[('Adam', 92), ('Bart', 66), ('Bob', 75), ('Lisa', 88)]
print(sorted(L, key=lambda t: t[1]))
[('Bart', 66), ('Bob', 75), ('Lisa', 88), ('Adam', 92)]
print(sorted(L, key=itemgetter(1), reverse=True))
[('Adam', 92), ('Lisa', 88), ('Bob', 75), ('Bart', 66)]
itemgetter() 根据某个或某几个字典字段来排序Python列表:
1.通过使用operator 模块的itemgetter 函数,可以非常容易的排序这样的数据结构
itemgetter() 函数也支持多个keys:
from operator import itemgetter
data = sorted(rows, key=itemgetter(‘na1’,‘na2’))
2.lambda表达式:
sorted(rows, key=lambda r: r[‘na1’])
itemgetter()有时候可以用lambda表达式代替,使用itemgetter() 方式会运行的稍微快点
3.min(),max()
最后,不要忘了这也同样适用于min() 和max() 等函数
rows = [{'fname': 'David', 'uid': 1002, 'lname': 'Beazley'},
{'fname': 'John', 'uid': 1001, 'lname': 'Cleese'},
{'fname': 'Big', 'uid': 1004, 'lname': 'Jones'},
{'fname': 'Brian', 'uid': 1003, 'lname': 'Jones'}]
>>> min(rows, key=itemgetter('uid'))
{'fname': 'John', 'lname': 'Cleese', 'uid': 1001}
>>> max(rows, key=itemgetter('uid'))
{'fname': 'Big', 'lname': 'Jones', 'uid': 1004}
sklearn的train_test_split
X_train,X_test, y_train, y_test
=cross_validation.train_test_split
(train_data,train_target,test_size=0.3, random_state=0)
参数解释:
train_data:被划分的样本特征集
train_target:label列,被划分的样本标签
test_size:如果是浮点数,在0-1之间,表示样本占比;如果是整数的话就是样本的数量
random_state:是随机数的种子。
随机数种子:其实就是该组随机数的编号,在需要重复试验的时候,保证得到一组一样的随机数。比如你每次都填1,其他参数一样的情况下你得到的随机数组是一样的。但填0或不填,每次都会不一样。
随机数的产生取决于种子,随机数和种子之间的关系遵从以下两个规则:
种子不同,产生不同的随机数;种子相同,即使实例不同也产生相同的随机数。
>>>import numpy as np
>>>from sklearn.model_selection import train_test_split
>>> X, y = np.arange(10).reshape((5, 2)), range(5)
>>> X
array([[0, 1],
[2, 3],
[4, 5],
[6, 7],
[8, 9]])
>>> list(y)
[0, 1, 2, 3, 4]
>>>X_train, X_test, y_train, y_test = train_test_split
(X, y, test_size=0.33, random_state=42)
X_train
y_train
X_test
y_test
时间格式转化
20141019072354 - 2014-10-19 07:23:54
data[u'发生时间'] = pd.to_datetime(data[u'发生时间'], format = '%Y%m%d%H%M%S')**
时间做差分
data[u’发生时间’].diff().head()
threshold = pd.Timedelta(‘4 min’)
---- Timedelta(‘0 days 00:04:00’)
d = data[u’发生时间’].diff() > threshold #相邻时间作差分,比较是否大于阈值
d.cumsum().head(10)
b = a.reset_index().sort_values(by=‘index’)
#导入输出相关的库,生成混淆矩阵
from sklearn import metrics
cm_train = metrics.confusion_matrix(y_train, model.predict_classes(x_train)) # 混淆矩阵
pd.DataFrame(cm_train, index = range(2), columns = range(2))
from statsmodels.tsa.stattools import adfuller as ADF
a = bic_matrix.idxmin()