Python库的实用技巧专栏

11,343 阅读9分钟

MedusaSorcerer的博客


专栏目录

专栏详情

collections

官方文档: https://docs.python.org/2/library/collections.html#collections.Counter

对列表数据元素进行数量统计

from collections import Counter

test_list = [1, 2, 3, 3, 2, 1, 1, 1, 2, 2, 3, 1, 2, 1, 1]

counter = Counter(test_list)
# 返回值: Counter({1: 7, 2: 5, 3: 3})

value = counter[2]
# 返回值: 5

# 实际上以上引入等价于以下代码:
counter = {i: test_list.count(i) for i in set(test_list)}
# 返回值: {1: 7, 2: 5, 3: 3}

对列表数据元素进行TOP统计

from collections import Counter

test_list = [1, 2, 3, 3, 2, 1, 1, 1, 2, 2, 3, 1, 2, 1, 1]

counter = Counter(lst)
result = counter.most_common(2)  # 统计TOP2
# 返回值: [(1, 7), (2, 5)]

对列表数据元素进行统计值相减

from collections import Counter

test1 = Counter(a=4, b=2, c=0, d=-2)
test2 = Counter(a=1, b=2, c=3, d=4, e=4)
test1.subtract(test2)
# 返回值:
# test1: Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})
# test2: Counter({'d': 4, 'c': 3, 'b': 2, 'a': 1})

对列表数据元素进行统计计算

from collections import Counter

test1 = Counter(a=4, b=2, c=0, d=-2)
test2 = Counter(a=1, b=2, c=3, d=4, e=4)

result1 = test1 + test2  # counter相加: 相同Key值相加, 不同Key保留
result2 = test1 - test2  # counter相减: 相同Key值相减, 不同Key用0代替再相减, 结果只保留value是正值的key
result3 = test1 & test2  # counter交集: 取相同key, value取小
result4 = test1 | test2  # counter并集: 取所有key, key相同时value取大
# 返回值:
# result1: Counter({'a': 5, 'b': 4, 'e': 4, 'c': 3, 'd': 2})
# result2: Counter({'a': 3})
# result3: Counter({'b': 2, 'a': 1})
# result4: Counter({'a': 4, 'd': 4, 'e': 4, 'c': 3, 'b': 2})

defaultdict

官方文档: https://docs.python.org/2/library/collections.html#collections.defaultdict

获取Dict不存在key

from collections import defaultdict

test = defaultdict(str)
test['key1'] = '1'
test['key2'] = '2'
# 获取不存在的Key将使用实例化的类型所对应的空对象作为初始化数据
# str -> "" | int -> 0 | list -> list() | dict -> dict() | set -> set() | tuple -> tuple() 
v = test['medusa']

# 返回值:
# v: ""
# test: defaultdict(<class 'str'>, {'key1': '1', 'key2': '2', 'medusa': ''})

deque

官方文档: https://docs.python.org/2/library/collections.html#collections.deque

指定长度的ListQueue

# First-In-First-Out,FIFO
from collections import deque

my_queue = deque(maxlen=10)

for i in range(10):
    my_queue.append(i+1)

print(my_queue)
# 输出: deque([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], maxlen=10)

print(my_queue.popleft())
# 输出: 1

for i in range(5):
    my_queue.append(i+1)
print(my_qeueu)
# 输出: deque([6, 7, 8, 9, 10, 1, 2, 3, 4, 5], maxlen=10)

namedtuple

官方文档: https://docs.python.org/2/library/collections.html#collections.namedtuple

tuple的指定索引对象

from collections import namedtuple

# 创建数据模板, 名称为Person, 数据模板域名称 name | description | forever | size
Person = namedtuple('Person', 'name description forever size')

# 使用模板创建两个索引对象, 两种方法等价
Medusa = Person(name='Medusa', description='Medusa blog', forever=True, size='Max')
You = Person._make(['You', '...', True, 'Max'])

print(Medusa)
print(You)
# 输出:
# Medusa: Person(name='Medusa', description='Medusa blog', forever=True, size='Max')
# You: Person(name='You', description='...', forever=True, size='Max')

# 修改属性值, 实际上生成了新的对象
update_Medusa = Medusa._replace(description='https://juejin.cn/user/2805609406139950')
print(Medusa)
print(update_Medusa)
# 输出:
# Medusa: Person(name='Medusa', description='Medusa blog', forever=True, size='Max')
# update_Medusa: Person(name='Medusa', description='https://juejin.cn/user/2805609406139950', forever=True, size='Max')

# 输出字典
print(Medusa._asdict())
# 输出: OrderedDict([('name', 'Medusa'), ('description', 'Medusa blog'), ('forever', True), ('size', 'Max')])

pandas + numpy

官方文档: https://www.pypandas.cn/

读取和写入文件数据

import pandas as pd

df = pd.DataFrame(pd.read_csv('csv_name.csv',header=1)) 
df = pd.DataFrame(pd.read_excel('xlsx_name.xlsx'))
ReadWrite
read_csvto_csv
read_excelto_excel
read_hdfto_hdf
read_sqlto_sql
read_jsonto_json
read_msgpack(experimental)to_msgpack(experimental)
read_htmlto_html
read_gbq (experimental)to_gbq (experimental)
read_statato_stata
read_sas-
read_clipboardto_clipboard
read_pickleto_pickle

read_csv参数说明

  • filepath_or_buffer: str 支持字符串或者任何可读文件对象, 包括UEL类型的文件
  • sep: str 指定数据分隔符, 默认尝试","分隔, 分隔符长于一个字符且不是"\s+", 将使用python的语法分析器, 并且忽略数据中的逗号
  • delimiter: str 定界符, 备选分隔符, 如果指定该参数, 则sep参数失效
  • delim_whitespace: bool 指定空格是否作为分隔符使用, 等效于设定sep="\s+", 如果这个参数设定为"True", 则delimiter参数失效
  • header: int or list of ints 指定行数编号作为列名, 如果文件中没有列名则默认为0, 否则设置为None, 如果明确设定header=0就会替换掉原来存在列名, 如果是list表示将文件中的这些行作为列标题(意味着每一列有多个标题), 介于中间的行将被忽略掉, 注意:如果skip_blank_lines=True, 那么header参数忽略注释行和空行, 所以header=0表示第一行数据而不是文件的第一行
  • names: array like 用于结果的列名列表, 若数据文件中没有列标题行则需要执行header=None, 默认列表中不能出现重复, 除非设定参数mangle_dupe_cols=True
  • index_col : int or sequence or False 用作行索引的列编号或者列名, 如果给定一个序列则有多个行索引, 如果文件不规则, 行尾有分隔符, 则可以设定index_col=False来使pandas不适用第一列作为行索引
  • usecols: array-like 返回一个数据子集, 该列表中的值必须可以对应到文件中的位置(数字可以对应到指定的列)或者是字符传为文件中的列名, 例如:usecols有效参数可能是 [0,1,2]或者是 [‘foo’, ‘bar’, ‘baz’], 使用这个参数可以加快加载速度并降低内存消耗。
  • as_recarray: bool 不支持使用:该参数会在未来版本移除, 请使用pd.read_csv(...).to_records()替代, 返回一个Numpy的recarray来替代DataFrame, 如果该参数设定为True, 将会优先squeeze参数使用, 并且行索引将不再可用, 索引列也将被忽略
  • squeeze: bool 如果文件值包含一列, 则返回一个Series
  • prefix: str 在没有列标题时, 给列添加前缀
  • mangle_dupe_cols : bool 重复的列, 将多个重复列表示为"X.0"..."X.N", 否则将列覆盖。
  • dtype: Type name or dict of column -> type 每列数据的数据类型
  • engine: "c" or "python" 指定分析引擎, C引擎快, 但是Python引擎功能更加完备
  • converters: dict 列转换函数的字典, key可以是列名或者列的序号
  • true_values: list Values to consider as True
  • false_values: list, Values to consider as False
  • skipinitialspace: bool 忽略分隔符后的空白
  • skiprows: list-like or integer 需要忽略的行数(从文件开始处算), 或需要跳过的行号列表
  • skipfooter: int 从文件尾部开始忽略
  • skip_footer: int 从文件尾部开始忽略(不推荐使用)
  • nrows: int 需要读取的行数(从文件头开始算起)
  • na_values: scalar, str, list-like, or dict 一组用于替换NA/NaN的值, 如果传递, 需要制定特定列的空值。默认为"1.#IND", "1.#QNAN", "N/A", "NA", "NULL", "NaN", "nan"
  • keep_default_na: bool 如果指定na_values参数, 并且keep_default_na=False, 那么默认的NaN将被覆盖, 否则添加
  • na_filter: bool 是否检查丢失值(空字符串或者是空值), 对于大文件来说数据集中没有空值, 设定na_filter=False可以提升读取速度
  • verbose: bool 是否打印各种解析器的输出信息
  • skip_blank_lines: bool 如果为True, 则跳过空行, 否则记为NaN
  • parse_dates: boolean or list of ints or names or list of lists or dict
    • 传递True将会解析索引
    • 传递list of ints or names(例如[1, 2, 3])将会解析1,2,3列的值作为独立的日期列
    • 传递list of lists(例如[[1, 3]])将会合并1,3列作为一个日期列使用
    • 传递dict(例如{"foo": [1, 3]})则将1,3列合并, 并给合并后的列起名为"foo"
  • infer_datetime_format: bool 如果设定为True并且parse_dates可用, 那么pandas将尝试转换为日期类型, 如果可以转换, 转换方法并解析。在某些情况下会快5~10倍
  • keep_date_col: bool 如果连接多列解析日期, 则保持参与连接的列
  • date_parser: function 用于解析日期的函数, 默认使用dateutil.parser.parser来做转换, Pandas尝试使用三种不同的方式解析, 如果遇到问题则使用下一种方式
    • 使用一个或者多个arrays(由parse_dates指定)作为参数
    • 连接指定多列字符串作为一个列作为参数
    • 每行调用一次date_parser函数来解析一个或者多个字符串(由parse_dates指定)作为参数
  • dayfirst: bool DD/MM格式的日期类型
  • iterator: bool 返回一个TextFileReader对象, 以便逐块处理文件
  • chunksize: int 文件块的大小
  • compression: "infer" or "gzip" or "bz2" or "zip" or "xz" or None 直接使用磁盘上的压缩文件, 如果使用infer参数, 将使用指定的方式解压指定后缀的文件
  • thousands: str 千分位分割符
  • decimal: str 字符中的小数点
  • float_precision: str Specifies which converter the C engine should use for floating-point values. The options are None for the ordinary converter, high for the high-precision converter, and round_trip for the round-trip converter
  • lineterminator : str 行分割符, 只在C解析器下使用
  • quotechar: str 引号, 用作标识开始和解释的字符, 引号内的分割符将被忽略
  • quoting: int or csv.QUOTE_* instance 控制csv中的引号常量, 可选 QUOTE_MINIMAL (0), QUOTE_ALL (1), QUOTE_NONNUMERIC (2) or QUOTE_NONE (3)
  • doublequote: bool 双引号, 当单引号已经被定义, 并且quoting 参数不是QUOTE_NONE的时候, 使用双引号表示引号内的元素作为一个元素使用
  • escapechar: str 当quoting 为QUOTE_NONE时, 指定一个字符使的不受分隔符限值
  • comment: str 标识着多余的行不被解析, 如果该字符出现在行首, 这一行将被全部忽略, 这个参数只能是一个字符, 空行(就像skip_blank_lines=True)注释行被header和skiprows忽略一样, 如果指定comment='#' 解析"#empty\na,b,c\n1,2,3" 以header=0 那么返回结果将是以’a,b,c'作为header
  • encoding: str 指定字符集类型, 通常指定为'utf-8'
  • dialect: str or csv.Dialect instance 如果没有指定特定的语言, 如果sep大于一个字符则忽略
  • tupleize_cols: bool Leave a list of tuples on columns as is (default is to convert to a Multi Index on the columns)
  • error_bad_lines: bool 如果一行包含太多的列, 那么默认不会返回DataFrame, 如果设置成False, 那么会将改行剔除(只能在C解析器下使用)
  • warn_bad_lines: bool 如果error_bad_lines=False, 并且warn_bad_lines=True 那么所有的"bad lines"将会被输出(只能在C解析器下使用)
  • low_memory: bool 分块加载到内存, 再低内存消耗中解析, 但是可能出现类型混淆, 确保类型不被混淆需要设置为False或者使用dtype参数指定类型, 注意使用chunksize或者iterator参数分块读入会将整个文件读入到一个Dataframe, 而忽略类型(只能在C解析器中有效)
  • buffer_lines: int 这个参数将会在未来版本移除, 因为他的值在解析器中不推荐使用(不推荐使用)
  • compact_ints: bool 这个参数将会在未来版本移除(不推荐使用), 如果设置compact_ints=True, 那么任何有整数类型构成的列将被按照最小的整数类型存储, 是否有符号将取决于use_unsigned参数
  • use_unsigned: bool 这个参数将会在未来版本移除(不推荐使用), 如果整数列被压缩(i.e. compact_ints=True), 指定被压缩的列是有符号还是无符号的
  • memory_map: bool 如果使用的文件在内存内, 那么直接map文件使用。使用这种方式可以避免文件再次进行IO操作