【Python】一些小tips

本文介绍了Python编程中的一些实用小技巧,包括安装Python包、数据处理、排序、日期格式化、条件筛选、数据清洗、数据类型转换等,涵盖了数据分析、数据处理和日志分析等多个方面。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

# 安装python包
# https://www.lfd.uci.edu/~gohlke/pythonlibs/
# python在windows上的第三方包,找到对应版本下载下来,用ftp传进172,再用 python -m pip install xxx.whl 来安装。

__author__ = 'Administrator'

import numpy as np
from collections import Counter
import pandas as pd
from pandas import DataFrame, Series

lst = [1, np.nan, 3, 4, np.nan, 5]
lstnan = np.isnan(lst)
lstcounts = Counter(lstnan)

print lstcounts

# df.loc[]是根据df的索引值来定位的,df.iloc[]是根据位置的从0~N的编号来定位的。
# bnd类型是Series
# input:(3,4), output:(1,2,3,1,2,3,4)
def getSeriesByBound(bnd):
    serial = []
    arr = bnd.values
    for x in arr:
        serial.extend(range(1,x+1))
    return Series(serial)

def handleDataFrame(df, fieldName, serialName, ratio):
    stkArr = df[fieldName].unique()
    resultDF = pd.DataFrame(columns=df.columns)
    for x in stkArr:
        dfTmp = df[df[fieldName]==x]
        ixSize = dfTmp.index.size
        # because the method: append() returns a new object, so I should
        # assign a new object to accept it.
        resultDF = resultDF.append(dfTmp[dfTmp[serialName] >= (1-ratio)*ixSize])
    return resultDF

# calculate mean and std by security_id
df_stat=df.groupby('security_id').describe()
df_stat.index.names=['sid','var']
df_stat=df_stat.query('var=="mean" or var=="std"')


df1=df[['stock_code','security_id','stock_cost','profit_ability']]
df_stat=df1.groupby('security_id').describe()
df_stat.index.names=['sid','var']
df_stat=df_stat.query('var=="mean" or var=="std"')
# 按照多列来排序
df1.sort_index(by=['security_id', 'profit_ability'], inplace=True)

# 读取前5行,并将第0列,即:period_id设置为索引index,且进行了日期格式化。
# df = pd.read_csv(file_path, nrows=20, parse_dates=[0], index_col=[0])
# df = pd.read_csv(file_path, nrows=20) 这里period_id是固定的,所以不能作为index。index要是唯一的嘛!
# df_realtime=pd.read_csv(r'D:\pyworkspace\airisk\dr.csv', dtype={'client_id':np.str}) 设置读取字段的类型
# 读取excel文件:
df = pd.read_excel(str_filename, header=0, dtype={'client_id':np.str}, sheetname='Sheet1')

# counts = Counter(np.isnan(df['stock_cost'])) 可以查看有多少nan值。

# 根据stock_cost这一列来进行dropna,如果这一列中有的行是NaN,则drop这一行
# df.shape查看DataFrame的大小
# df.dropna(subset=['stock_cost'], inplace=True)


# 查看stock_cost这一列还有没有缺失值,答案是没有
# df['stock_cost'].isnull().value_counts()
# 对Series按值进行排序,用order()方法。df['stock_cost'].order()

# 计算盈利能力指标
# df['profit_ability']=100*df['stock_profit']/df['stock_cost']
# df = dfa[['stock_code','profit_ability']] 选取dfa中的stock_code和profit_ability两行作为df

# 对于MultiIndex,使用test.query('ilevel_0=="7"') 这样的形式来查询数据,如果index有名字,就用index的名字,不能用ilevel_0这样的形式。
# test= test=df1.groupby('stock_code').describe()
# df_stat=test.query('ilevel_1=="mean" or ilevel_1=="std"')


# 根据stock_code排序就相当于是根据stock_code做groupby了。
# df_sorted=df.sort_index(by=['stock_code','profit_ability'])
# 上面这个方式是生成一个新的DataFrame,可以增加inplace=True选项。
# df1_sorted=df1.sort_index(by=['stock_code','profit_ability'],inplace=True)


# 查看分组之后的各组大小,
# df1.groupby('stock_code').size()

# 根据列名来删除列,加上axis=1
# df1.drop('serial', axis=1, inplace=True)
# 永久删除 del df1['serial']
# 删除多列
# df1.drop(['cola','colb'], axis=1, inplace=True)
# 删除行
tt.drop([0], inplace=True) # 删除索引=0的行。


# 给df1加上一列serial,注意:如果s为Series,则必须是 df1['serial1']=s.values,左边是Series,右边是list。
# df1.loc[:,'serial']=s.values
# df1['serial1']=s.values
# baseDF['flag']=pd.Series(ones(baseDF.shape[0])) 添加全1的列


# DataFrame和Series都有属性size,而不是方法.
# 创建一个只有列名的DataFrame: dfr = DataFrame(columns=['stock_code','security_id','stock_cost','profit_ability'])
# dfr=pd.DataFrame(columns=df1.columns)

# fetchone()返回的是tuple,取收盘价要closePrice[0];而fetchall()返回的是list,取收盘价是closePrice[0][0]

for i in range(df_stat.shape[0]):
     if i % 2 == 0:
          dft = df1[df1['stock_code'] == df_stat['stock_code'][i]]
          dfr = dfr.append(dft[dft['stock_cost'] > df_stat['stock_cost'][i]])

# 2016-6-24 标准化数据
# 1. 自己写代码实现,这里的baseDF是DataFrame格式
def standardizeData(baseDF):
    meanVal = baseDF.mean(axis=0)
    stdVal=baseDF.std(axis=0)
    baseDF = (baseDF - meanVal)/stdVal
    return baseDF
# 2. 利用sklear包
from sklearn import preprocessing
baseDF = pd.DataFrame()
scaled = pd.DataFrame(preprocessing.scale(baseDF))
# 3. 利用 StandardScaler 类
scaler = preprocessing.StandardScaler.fit(baseDF)
result = pd.DataFrame(scaler.transform(baseDF))

'''
date: 2016-11-24
'''
# 取df的前几列,通过列的编号来取,而不是列名
df = pd.DataFrame()
df.iloc[:,0:3] 

'''
date: 2017-11-11
'''
a=python a[::-1]=?
# 将列表a倒序处理,如果a=[1,2,3],则a[::-1]=[3,2,1]。
# 前两个冒号表示处理整个列表,也可以写上参数表示处理列表的一部分,例如a[2:0:-1]=[3,2],
# 第一个参数表示起始点包括起始点,第二个参数表示结束点但不包括结束点。
# 最后一个参数如果为负的话,需要保证第一个参数大于第二个参数,表示依次递减逆序,否则会输出空列表。最后一个参数为正同理。


# 多个条件选取行
df[np.logical_and(df['one']> 5,df['two']>5)]

# 将df的某一列(由数字表示的日期)转换为日期格式
period_df['period_idd']=[pd.datetime.strptime(str(x), '%Y%m%d') 
    for x in period_df['period_id']]
    
# 判断是否有NULL值。
dt_profit.isnull().any()

# 2018-1-22 困扰太久。
# 注意:当利用df['col_name'] =s 来新建列并且赋值的时候,如果右边是Series 等带索引的object时,默认是按照index 来赋值的。
# 为避免引起误解,要么df.reset_index(inplace=True), 要么右边是标量。

# 当在交互模式下导入自己写的module时,需要sys.path.apend(my_path). 这样就可以在pycharm下用interactive module了,不需要spyder.

#2018-3-12 困扰太久。
# 当join时,如果设置了multiindex, 那么两个dataframe的index名字(两对)必须完全一样,不能df_price.set_index(['fund_code','period_id'])
# 而df_min_period.set_index(['fund_code','min_period_id'],否则会报错:
# NotImplementedError: merging with both multi-indexes is not implemented
df_min_period_price = df_price.set_index(['fund_code','period_id']).join(df_min_period.set_index(['fund_code','period_id']),
    lsuffix='_caller', rsuffix='_other', how='inner').reset_index()


#注意:不同的写法,返回的类型不同
data.iloc[-1]   #选取DataFrame最后一行,返回的是Series
data.iloc[-1:]   #选取DataFrame最后一行,返回的是DataFrame
data.iloc[:1] #返回第一行,类型DataFrame
data.iloc[0] #返回第一行,类型Series


# 注意:这里and 不能改为 &, and 时如果前面结果为False,则不会执行后面的判断.但是&都会判断.
while ((p < df.index[-1]) and (df.loc[p].mkt_business_amount == df.loc[p+1].mkt_business_amount)):

# 2018-7-11 给DataFrame赋值的问题
df_null.iloc[0]['stock_code']='shmlx' #这种会报警
dfmi['one']['second'] = value
# becomes
dfmi.__getitem__('one').__setitem__('second', value)
###===========================================================
df_null.loc[154,'stock_code']='shml' #这种不会告警。loc是直接更新的原数据。
dfmi.loc[:,('one','second')] = value
# becomes
dfmi.loc.__setitem__((slice(None), ('one', 'second')), value)

#实现count(distinct ispull)的逻辑
df1=df.groupby(['stock_code','exchange_type']).agg({'ispull':pd.Series.nunique})
#当调用count()函数之后,要执行.reset_index才能返回DataFrame格式的数据。
df1=df.groupby(['stock_code','exchange_type','ispull','rec_date']).count().reset_index()

# DataFrame给列重命名. 注意:要加上columns=.
df.rename(columns={'oc_time':'min_busi_time_hq_time', 'last_price':'min_busi_time_hq', 'close_price':'close_price_hq'}, inplace = True)

# 2018-8-1。这里不能写成 grpc_util,中间不能有_,否则报找不到方法。
import grpcutil as grpc
# 2018-8-2 可以在groupby(by=, as_index=False)直接去掉groupby字段的index属性.
df.groupby(by=['Mt'], as_index=False).agg(max)
# 找出最大值所在的行
# 方法1:在分组中过滤出Count最大的行
df = pd.DataFrame({'Sp':['a','b','c','d','e','f'], 'Mt':['s1', 's1', 's2','s2','s2','s3'], 
    'Value':[1,2,3,4,5,6], 'Count':[3,2,5,10,10,6]})
df.groupby('Mt').apply(lambda t: t[t.Count==t.Count.max()])
#方法2:用transform获取原dataframe的index,然后过滤出需要的行
idx=df.groupby(['Mt'])['Count'].transform(max)
print idx
idx1 = idx == df['Count']
print idx1
df[idx1]
# 上面的方法都有个问题是3、4行的值都是最大值,这样返回了多行,如果只要返回一行呢?
# 方法3:idmax(旧版本pandas是argmax)
idx = df.groupby('Mt')['Count'].idxmax()
print idx
df.iloc[idx]

df.iloc[df.groupby(['Mt']).apply(lambda x: x['Count'].idxmax())]
# 方法4:先排好序,然后每组取第一个
df.sort('Count', ascending=False).groupby('Mt', as_index=False).first()

# 2018-8-7 iterrows()可能会更改字段类型:会把int64型的MDTime,改为float64.导致:datetime.datetime.strptime(str(int(r.MDTime)), '%H%M%S')
# 格式化时间出错:来自:LNSIW_JC_2.py
for i, r in df_endp.iterrows():

# 多维list按照第二维排序
lt_reset.sort(key=lambda x : x[1])

# python多维list不支持取其中的一维:也正因为列表可以存放不同类型的数据,因此列表中每个元素的大小可以相同,
# 也可以不同,也就不支持一次性读取一列,即使是对于标准的二维数字列表

# 当对某一个iterable对象进行遍历时,为了增加一列自然编号序列,可以用enumerate(list)来。
for i, t in enumerate(lt):
    ...
# 而不用 
for i, t in zip(lt, np.arange(lt.__len__())):

#选择模型的参考
http://scikit-learn.org/stable/tutorial/machine_learning_map/

# Python 四舍五入的方法,非round()
# 用 Decimal
from decimal import Decimal
aa = Decimal('5.026').quantize(Decimal('0.00'))
bb = Decimal('3.555').quantize(Decimal('0.00'))
print(aa)
print(bb)

# 把行向量X转成列向量
X.reshape(-1,1)
# 2018-10-18 刷新导入的第三方模块
# 在开发时,如果修改了impala_app_util.py, 则:
import importlib
importlib.reload(imp_app)
# 再执行即可.

#python2 & 3 除法的不同
# python2 中默认的是舍去式除法(floor division),python3中不是这样的,舍去式除法是://

# python代码格式检查, conda list 中已默认安装了 pep8.
pep8 --first RWOIOCA_backtest.py #  最简单的监测方式
pep8 --show-source --show-pep8 RWOIOCA_backtest.py # 显示具体的出错的代码位置
pep8 --statistics -qq RWOIOCA_backtest.py
# 类似的代码监测工具:Pychecker(Google Python Style Guide), Pylint(方便的通过配置文件来设置风格), Pyflakes(易于集成于vim中).

# python 中:
# 单*号,对元组解包
# 双*号,对字典解包

# 安全的eval
import ast
ast.literal_eval('')

# python 中有 ++i, ++1, 但是并不会自增

# Generator contextlib 处理函数级别的上下文.

# 对DataFrame的每一行截取前4个字符.
df_time['hour_min'] = df_time[df_time.columns[0]].apply(lambda x : str(x)[:4])

# 在IPython中,查看python源码。
# insert2db? / insert2db??, 一个?表示查看函数的文档,??表示查看其Python源代码,如果函数不是Python写的,则查看不到。
# 注意,函数名和?之间不要有空格.

# pd.merge_asof(left_df, right_df, left_on='', right_on=''), 注意:left_on和right_on 只能是一个label,如果是功能的stock_code,
# 需放在by参数中。另外int32 & int64 都不能同时作为left_on和right_on字段的类型,会报类型不匹配的错误。
# astype(np.int) 是int32, 而 lambda x: int(x) 是int64.

# 若不想让默认参数所指向的对象在所有的函数调用中被共享,而是在函数调用的过程中动态生成,可以在定义的时候使用None对象作为占位符。

# str() 与 repr(): 
# 1. str()主要面向用户,其目的是可读性,返回形式为用户友好性和可读性都较强的字符串类型。
#      repr()面向的是Python解释器,或者是开发人员,其目的是准确性,其返回值表示Python解释器内部的含义,常作为编程人员debug用途。
# 2. 在解释器中直接输入a时默认调用repr()函数,而print(a)则调用str()函数。
# 3. repr()的返回值一般可以用eval()函数来还原对象,通常来说有:obj == eval(repr(obj))
# 4. 一般类中都应该定义__repr__()方法,而__str__()为可选。

# 当在解释器中输入长字符串时,用小括号,而非3个连续的单(双)引号(会把换行符也当做字符串的一部分)。
# 在python 2中,字符串包含str&unicode两类,其基类是basestring.

# find()函数族找不到时返回-1,index()函数族则抛出VauleError异常。 但对于判定是否包含子串并不推荐调用这些方法,二是推荐使用in和not in操作符。

# 字符串分隔:partition和split. s.split() 和 s.split(' ')返回结果是不一样的。不存在 s.split('') 这个方法参数。

# 排序:sorted() 应用于任何可迭代的对象,而s.sort() 一般用于列表。
# sorted()会返回一个排序后的新列表,原列表不变。 而sort()函数会直接修改原有列表(由于不需要复制原有列表,消耗的内存少,效率也较高),函数返回值None.
# 传入key 比 cmp 效率要高很多。
# sorted(students, key=operator.itemgetter(1,2)). from operator import itemgetter.  根据第二列和第三列来排序。

# from collections import Counter. 使用Counter来计数.


import ConfigParser

conf = ConfigParser.ConfigParser()
conf.read('example.conf')
print(conf.get('section1', 'in_default'))

# 关于:Pythonista, Pythoneer, Pythonist
# 其实正确的理解是加-eer,意思是「从事…的人」
# Pythoneer:使用python语言开发程序的人
# Pythonista:顾名思义表示「Python支持者」,更表示资深的,对代码质量和品味有要求的开发者,这种执念也就是所谓「Pythonic」。
# 这也是为什么称自己为Pythonista的人最多的原因了。
# Pythonist:-ist这种后缀表示职业中有一定的信念,有专家角度,如scientist、physicist、chemist,还给人严肃且不活泼的感觉,所以用的人很少。

# 所以正确的用法,请大家大声的和我念一遍:Pythonista!!

# REST 风格的Python第三方库.
# falcon比flask、Django是开发rest api更直接简单,后两者还用来做web应用,功能比较全,更复杂.
# https://falcon.readthedocs.io/en/stable/user/quickstart.html


# GIL是什么
# GIL(Global Interpreter Lock)
# 首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念。
# 就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代码。有名的编译器例如GCC,INTEL C++,Visual C++等。
# Python也一样,同样一段代码可以通过CPython,PyPy,Psyco等不同的Python执行环境来执行。像其中的JPython就没有GIL。
# 然而因为CPython是大部分环境下默认的Python执行环境。所以在很多人的概念里CPython就是Python,也就想当然的把GIL归结为Python语言的缺陷。
# 所以这里要先明确一点:GIL并不是Python的特性,Python完全可以不依赖于GIL。
# 那么CPython实现中的GIL又是什么呢?GIL全称Global Interpreter Lock为了避免误导,我们还是来看一下官方给出的解释:
# In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. 
# This lock is necessary mainly because CPython’s memory management is not thread-safe. 
# (However, since the GIL exists, other features have grown to depend on the guarantees that it enforces.)

# threading 支持守护线程,而thread模块不支持。
# 在主线程中,启用new thread(比如t2),如果设置:t2.setDaemon(True),则主线程可以不用等待t2执行完成才退出。
# 当daemon属性设置为False,默认主线程会等待所有子线程结束后才会退出。

# Python 3中已经不存在thread模块,thread模块在Python 3中被命名为_thread,这种更改主要是为了更进一步明确表示与thread模块
# 相关的更多是具体的实现细节,它更多展示的是OS层面的原始操作和处理,在一般的代码中不应该选择thread模块。

# https://www.cnblogs.com/SuKiWX/p/8804974.html python中的GIL详解

# 2018-11-23
# groupby.agg函数中拼接字符串
df1.groupby(by=['grp']).agg({'cat':':'.join})

# 2018-11-27 在程序中当有两个空的dataframe来merge时,on最多只能一个字段,>=2个将会报错.
df1.merge(df2, on=['stock_code','exchange_type'])
C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\reshape\merge.py:1457: RuntimeWarning: divide by zero encountered in longlong_scalars
  stride //= shape[i]

# 2018-12-11 基于Qt框架的富文本编辑器
ipython qtconsole --pylab=inline
# 根据dataframe中的多列来生成新列,其中的r表示整行row,可以用下标来取对应的值,类似dataframe的itertuples(index=False)
df_self_grp['self_amt'] = df_self_grp.apply(lambda r: r.busi_amt_2 if r.busi_amt_1 >= r.busi_amt_2 else r.busi_amt_1, axis=1)

#  2018-12-23
# 开源组织:github.com 和 https://www.openhub.net/
# python web framework.
Django: https://www.djangoproject.com/  # 内置的ORM功能,而Flask没有.
Pylons: https://www.djangoproject.com/
TurboGears: http://www.turbogears.org/
Tornado: http://www.tornadoweb.org/en/stable/
Zope: http://www.zope.org/en/latest/
Plone: https://plone.org/ The Ultimate Enterprise CMS
# 事件驱动的框架
Twisted: https://twistedmatrix.com/trac/  Building the engine of your internet. 还不能完全支持python 3
Circuits: https://bitbucket.org/prologic/circuits
# REST框架
Falcon: https://falcon.readthedocs.io/en/stable/index.html

# 2018-12-24 选取第几列
df.iloc[:, 0] 
df.iloc[:, [1,2]

# 2019-1-4 经搜索得知,是thrift-sasl的版本太高了(0.3.0),故将thrift-sasl的版本降级到0.2.1
# 经测试impyla 可以正常使用。
pip install thrift-sasl==0.2.1

# 2019-1-7 np.count_nonzero() 和 np.sum()不一样
lt
Out[192]: [True, False, False, nan]
np.sum(lt)
Out[193]: nan
np.count_nonzero(lt)
Out[194]: 2

# 2019-1-11 dataframe中的某一列按照某个分隔符分隔,扩展成行. 需要用到join.
df_t = df_client['client_ids'].str.split(',', expand=True).stack().replace('', np.nan).dropna()
df_t = df_t.reset_index(level=1, drop=True).rename('client_id')
df_client = df_client.join(df_t)

# 2019-1-16 groupby时,判断是否包含某个值
df.groupby(by=['id'])['branch_no'].apply(lambda x: x.values.__contains__(205))

# 2019-1-17 python 程序运行时间
# method 1 datetime
import datetime
starttime = datetime.datetime.now()
# run
endtime = datetime.datetime.now()
print (endtime - starttime).seconds
# method 2 time
start = time.time()
# run
end = time.time()
print end-start
# method 3 time.clock()
start = time.clock()
# run
end = time.clock()
print end-start
# 方法1和方法2都包含了其他程序使用CPU的时间,是程序开始到程序结束的运行时间。
# 方法3算只计算了程序运行的CPU时间

# 2019-1-22 实现类似string_agg(distinct col_name)的功能.
df.groupby.agg({'cols': lambda x: ','.join(np.unique(x))})

# 在apply的时候,df[['col_1','col_2']].apply(lambda x: x, axis=1)这里lambda函数只有一个x参数,且加上axis=1表示按列来。
# dataframe中以行来做并集,而且每行还需要用逗号split
lambda x: ','.join(set(x.str.split(',', expand=True).stack().reset_index(level=1, drop=True)))

# 2019-1-29 切换python第三方包的安装源
http://wiki.xxx.com.cn/pages/viewpage.action?pageId=1234567890

# 2019-2-18 多个条件in
df_realt = df_realt[(df_realt.acode_account + df_realt.stock_code).isin(
    (df_acode_stk.acode.values + df_acode_stk.stock_code.values).tolist())]

# 下面代码中的period_idd类型是:pandas._libs.tslib.Timestamp, 其weekday()周一~周五是:0123456,
# df_period['period_idd'] = [pd.datetime.strptime(str(x), '%Y%m%d') for x in df_period['period_id']]
# 此处+1,以应对周一到周五.
# 而datetime.date(2019, 3, 21).strftime('%w') 周一~周五是:1234560

# 2019-3-27 df.index.values 和 df['index'].values 的区别:如果df在上一步执行了 df.reset_index(inplace=True)
# 则df中会有一列名为index. 此时df['index']仍是取这一列,但是df.index是取df的索引列。

# df.join 默认的是left, df.merge 默认的是inner.

# 2019-4-18 python正则表达式
def find_stock_code(letter_info, dt):
    '''
    根据股票名称查询股票代码.
    :param letter_info:
    :param dt:
    :return:
    '''
    letter_info = re.sub(r'”', '\"', letter_info)
    letter_info = re.sub(r'“', '\"', letter_info)
    # stock_name_groups = re.search(r'\"([^\"]*)\"', letter_info) # search只能返回第一个匹配到的记录. 当没有匹配到时返回None, 需用result is None来判断.
    stock_name_groups = re.findall(r'\"([^\"]*)\"', letter_info) #返回list,用len(result)即可.
    if len(stock_name_groups)==1:
        stock_name = stock_name_groups[0]
        print('stock_name=%s' % stock_name)
        # stock_name = re.search(r'\"([^\"]*)\"', letter_info).group()
        sql = "select stock_code from his_ht_hs08_hsuser.stkcode where dc_business_date=%s and stock_name=\'%s\'" % (
        dt, stock_name)
        df = db.select(sql)
        print('select df=%s' % (df[0][0] if df.shape[0] >0 else 'xxxxxx' ))
        return (df[0][0] if df.shape[0] >0 else 'xxxxxx')
    else: # 匹配到本0个或多个,目前(20180713)需要手工调整.
        return 'xxxxxx'
        
# 提取

def load_pull_press_letter(bgn_dt=20170501):
    '''
    加载函件数据.
    match只从开头匹配,search是搜索整个字符串.
    :param bgn_dt: 
    :return: 
    '''
    sql = "select client_id, stock_account, letter_type, letter_info, " \
          "rec_date, letter_source, rep_date from src_ht_risk.vclientsituation_to_crm t1 where rec_date>=%s " % (bgn_dt)
    df = db.select(sql)
    df.columns=['client_id', 'stock_account', 'letter_type', 'letter_info', 'rec_date', 'letter_source', 'rep_date']
    # 拉抬, 打压.
    df=df[ (df['letter_info'].str.contains('拉抬')) | (df['letter_info'].str.contains('打压'))]
    # 股转公司
    df = df[~ (df['letter_source']=='股转公司')]
    #  find stock code
    #pattern = re.compile(r'[0|3|6]{1}[0-9]{5}')
    df['stock_code']=df['letter_info'].str.extract('(?:\D)([0|3|6]{1}[0-9]{5})(?:\D)', expand=False) #(?:exp) 匹配exp,不捕获匹配的文本
    # Cannot be matched, then search double quotation.
    for i in df[df.stock_code.isnull()].index:
        df.loc[i]['stock_code']=find_stock_code(df.loc[i].letter_info, int(df.loc[i].rec_date))
    return df
# 匹配冒号和分号之间的内容多次:注意小括号内的? 表示非贪婪匹配。
exp = re.compile(r':(.*?)[;|;]')

# 从名字当中提取包含"特殊字符"任意两个字符的逻辑:
df['match'] = df['client_name'].apply(lambda x: re.search(r"[特殊字符]{2,}", x).group() if re.search(r"[特殊字符]{2,}", x) != None else '0')

# subprocess.call() 调linux shell命令。
# linux的ll命令,是ls -l的别名,相当于windows的快捷方式,不能通过sp.call('ll', shell=True)来执行.

# 全局变量
# 因为与其他语言不同,Python中的if语句不会再引入一个新的作用域(scope),任何变量分配的都是全局变量(global)。
# 这也解释了为什么它是一个错误,作为一个全局变量,在使用变量名之前是不允许再一次声明为全局变量, 这是多余的。 
# 简言之, if __name__==’__main__’: 中的变量都是全局的,所以你在这中间再一次声明global是错误的,所以系统会发出警告。

# 2020-1-7 Python对于小的int用得比较多。
x = 256
y = 256
id(x) == id(y)
Out[67]: True
x = 257
y = 257
id(x) == id(y)
Out[68]: False

# 2020-5-7 17个python操作
# 1.变换变量值
"""pythonic way of value swapping"""
a, b = 5, 10
print(a, b)
a, b = b, a
print(a, b)
# 2.将列表中的所有元素组合成字符串
a=['python','is','awesome']
print(" ".join(a))
# 3.查找列表中频率最高的值
"""most frequent element in a list"""
a=[1,2,3,1,2,3,2,2,4,5,1]
print(max(set(a), key=a.count))
"""using Counter from collections"""
from collections import Counter
cnt = Counter(a)
print(cnt.most_common(3))
# 4.检查两个字符串是不是由相同字母不同顺序组成
from collections import Counter
Counter(str1)==Counter(str2)
# 5.反转字符串
a='abcdefghijklmnopqrstuvwxyz'
print(a[::-1])
for char in reversed(a):
    print(char)
num=123456789
print(int(str(num)[::-1]))
# 6.反转列表
a=[5,4,3,2,1]
print(a[::-1])
for ele in reversed(a):
    print(ele)
# 7.转置二维数组
original = [['a','b'],['c','d'],['e','f']]
transposed = zip(*original)
print(list(transposed))
# 8.链式比较
b=6
print(4 < b < 7)
print(1 == b < 20)
# 9.链式函数调用,以下返回35
def product(a, b):
    return a * b
def add(a, b):
    return a + b
b = True
print((product if b else add)(5, 7))
# 10.复制列表
a=[1,2,3,4,5]
b=a  # shallow copy
b[0]=10  # both a and b will be [10,2,3,4,5]

a=[1,2,3,4,5]
b=a[:]  # deep copy
b[0]=10  # only b will change to [10,2,3,4,5]
#
a=[1,2,3,4,5]
b=a.copy()  # deep copy

from copy import deepcopy
l = [[1,2],[3,4]]
l2 = deepcopy(l)
print(l2)
# 11.字典get方法
"""return None or default value when key is not in dict"""
d={'a':1, 'b':2}
print(d.get('c', 3))
# 12.通过"键"排序字典元素
d = {'apple':10, 'orange':20, 'banana':5, 'rotten tomato':1}
print(sorted(d.items(), key=lambda x: x[1]))
"""sort using operator.itemgetter as the sort key instead of a lambda"""
from operator import itemgetter
print(sorted(d.items(), key=itemgetter(1)))
"""sort dict keys by value"""
print(sorted(d, key=d.get))
# 13. For Else
a=[1,2,3,4,5]
for el in a:
    if el == 0:
        break
else:
    print('did not break out of for loop')
# 14.转换列表为逗号分割符格式
"""converts list to comma separated string"""
data=[2, 'hello', 3, 3.4]
print(','.join(map(str, data)))
# 15.合并字典
d1={'a':1}
d2={'b':2}
print({**d1, **d2})
print(dict(d1.items() | d2.items()))
d1.update(d2)
# 16.列表中最小和最大值的索引
lst=[40,10,20,30]
def minIndex(lst):
    return min(range(len(lst)), key=lst.__getitem__)
def maxIndex(lst):
    return max(range(len(lst)), key=lst.__getitem__)
# 17.移除列表中的重复元素
items=[2,2,3,3,1]
newitems = list(set(items))
from collections import OrderedDict
list(OrderedDict.fromkeys(items).keys())

# 2021.8.31 pip更新第三方包
pip install --upgrade pandas 

# 2021.11.18 字符串匹配多个关键字,获取每个关键字的匹配次数
str_re = '|'.join(re.sub(' +', ' ', obj_str).split(" "))  # 按空格切分之后按|拼接关键字串, obj_str是要搜索的关键字串
all_str = re.finditer(r'%s' % str_re, src_str)  # src_str是搜索文本
count_dict = {}
for s in all_str:
  # s.group()方法用于从s中返回相应的字符串; setdefault()方法用户更新count_dict字典中对应key的value,返回值为数字。
  count_dict[s.group()] = count_dict.setdefault(s.group(), 0) + 1
count_dict = sorted(count_dict.items(), key=lambda k: k[1], reverse=True)


 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值