Jiahong 的个人博客

凡事预则立,不预则废


  • Home

  • Tags

  • Archives

  • Navigation

  • Search

Python-Jupyter——安装pip包

安装pip包


在Jupyter环境中安装pip包

  • 为了方便使用,我们一般会选择将Jupyter的内核切换为某个特定的虚拟Python环境,切换后,Jupyter的Python命令会按照新环境运行,但是安装软件包不会默认安装到当前环境(而是base环境)

  • 直接使用下面的命令安装会安装在base环境中

    1
    !pip install xxx
  • 如果想要安装在当前运行环境中,可以使用下面的命令

    1
    2
    import sys
    !{sys.executable} -m pip install xxx

Python——如何优雅的导入自定义的Python包


对于IDEA的管理

  • 在IDEA中运行文件时,当前项目根目录会默认被添加为Python的搜索路径
  • 根目录下的文件可以直接被访问
  • 根目录的子目录需要每一层都添加__init__.py文件,将其编译为包

IDEA项目用命令行运行

  • 在运行的第一个文件中添加IDEA项目的根目录作为搜索路径

    • 这里的根目录最好是绝对路径

      1
      2
      import sys
      sys.path.append("/home/xxx/xxx/xxx")
    • 如果是想使用相对路径,从而方便移植也行,但需要获取当前文件的文件路径,然后从当前文件与根目录的关系解析出根目录

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      import os
      thisFileDir = os.path.split(os.path.realpath(__file__))[0]
      # we have to modify the tail if we change the path of this python file
      tail = 6
      rootPath = thisFileDir[0:-tail]
      if rootPath[-1] != "/" and rootPath[-1] != "\\":
      message = "Error root path [%s]\n\tPlease check whether you changed the path of current file" % rootPath
      raise Exception(message)
      print "Current root path: %s" % rootPath

      import sys
      sys.path.append(rootPath)
  • 其他的和在IDEA中运行一样,需要添加的库加上__init__.py即可

Python——OrderedDict类的使用


整体说明

  • OrderedDict 是 Python 标准库中的一个类,它位于 collections 模块下
  • 相对于普通字典,OrderedDict 能够记住元素插入的顺序,在迭代时,元素会按照插入的先后顺序被返回
  • OrderedDict 类对象的主要特点有:
    • 仍然是一个字典 :即仍然是 Key-Value 结构,且 Key 值不能重复
    • 保持插入顺序 :迭代时,元素会按照插入的顺序返回
    • 顺序敏感 :如果两个 OrderedDict 包含相同内容,但元素插入顺序不同,它们会被视为不相等
    • 支持移动操作 :可以通过 move_to_end() 方法将元素移动到开头或末尾
    • 删除操作保留顺序 :删除元素后,剩余元素的顺序保持不变

OrderedDict 的基本用法

  • OrderedDict 的一些常见操作示例:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    from collections import OrderedDict

    od = OrderedDict()
    od['a'] = 1
    od['b'] = 2
    od['c'] = 3
    od['b'] = 10

    # 迭代时保持插入顺序
    for key, value in od.items():
    print(key, value) # 输出: a 1, b 10, c 3

    print('---')
    # 移动元素到开始
    od.move_to_end('b', last=False)
    for key, value in od.items():
    print(key, value) # 输出: b 10, a 1, c 3

    print('---')
    # 移动元素到末尾
    od.move_to_end('b', last=True)
    for key, value in od.items():
    print(key, value) # 输出: a 1, c 3, b 10

    print('---')
    # 删除元素后结果不变
    del od['c']
    for key, value in od.items():
    print(key, value) # 输出: a 1, b 10

比较:与普通字典的区别

  • 在 Python 3.7 及以后的版本中,普通字典也会保持插入顺序,但 OrderedDict 仍然有其独特优势:
    • 明确的顺序语义 :使用 OrderedDict 可以更清晰地表达代码对顺序的依赖
    • 支持顺序相关的方法 :如 move_to_end()、popitem(last=False) 等,且这两个函数都可以通过 last 参数指定是操作第一个还是最后一个
    • 顺序敏感的比较 :两个字典即使包含元素相同,但元素顺序不同也会被视为不等

Python——list返回最大的K个元素的索引

自定义的一个有用的Python方法


返回最大的K个值的索引

引用自Stack Overflow

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
def get_top_k_indexes_of_list(target_list, k, is_max=True, min_value=None):
"""
get the top k indexes of elements in list
Example:
Problem: I have a list say a = [5,3,1,4,10],
and I need to get a index of top two values of the list viz 5 and 10.
Is there a one-liner that python offers for such a case?
Usage: get_top_k_indexes_of_list(target_list=a, k=2, is_max=True)
link: https://stackoverflow.com/questions/13070461/get-index-of-the-top-n-values-of-a-list-in-python
:param target_list: target list
:param k: the number of indexes
:param is_max: True means max else False means min
:param min_value: if min_value is not None
filter the indexes whose value less than or equals to min_value
:return: a list of indexes
"""
indexes = sorted(range(len(target_list)), key=lambda i: target_list[i], reverse=is_max)[:k]
result = list()
if min_value is not None:
for index in indexes:
if target_list[index] <= min_value:
break
result.append(index)
else:
result = indexes
return result

一次性索引出多个元素

1
2
3
4
5
6
7
8
9
def get_elements_from_list(target_list, indexes):
"""
get elements from target_list by indexes
:param target_list: target list
:param indexes: a list of indexes
:return: a list of elements
"""
elements = [target_list[i] for i in indexes]
return elements

Python——partial函数的使用


整体说明

  • 在 Python 里,functools 模块中的 partial 函数能够用来创建新函数,这些新函数是对现有函数部分参数预先赋值后的版本

  • 借助这种方式,能简化函数调用,让代码更为简洁,常用在一些较为专业的底层框架中

  • 函数形式:

    1
    2
    3
    from functools import partial

    new_func = partial(func, *args, **kwargs)
    • func 代表原函数
    • args 和 kwargs 分别是要预先设置的位置参数和关键字参数
    • 调用 new_func 时,只需传入剩余未预先设置的参数就行

固定函数参数

  • 假设存在一个加法函数 add(a, b),现在要创建一个专门用于加 10 的新函数:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    from functools import partial

    def add(a, b):
    return a + b

    add_ten = partial(add, 10) # 把 a 固定为 10

    print(add_ten(5)) # 输出 15(也就是 10 + 5)
    print(add_ten(10)) # 输出 20(也就是 10 + 10)
    print(add_ten(5, 20)) # 输出 25(此时 10 被 5 覆盖,函数计算的是 5 + 20)
    • 注意:固定的是第一个参数

处理关键字参数

  • 在处理关键字参数 Demo:

    1
    2
    3
    4
    5
    6
    7
    8
    def power(base, exponent):
    return base ** exponent

    square = partial(power, exponent=2) # 固定 exponent 为 2
    cube = partial(power, exponent=3) # 固定 exponent 为 3

    print(square(5)) # 输出 25(即 5^2)
    print(cube(5)) # 输出 125(即 5^3)
    • 注意:可通过关键字参数指明具体参数

需要注意的点

  • 参数顺序问题 :使用 partial 固定参数时,参数是按照位置依次绑定的

    • 比如 partial(func, 10) 会把 10 绑定到 func 的第一个参数上
  • 参数覆盖 :如果预先设置的参数在新函数调用时又被传入了新值,那么新传入的值会覆盖预先设置的值

    • 例如:
      1
      2
      3
      add_ten = partial(add, 10)
      print(add_ten(5)) # 输出 15
      print(add_ten(5, 20)) # 输出 25(此时 10 被 5 覆盖,函数计算的是 5 + 20)
  • 函数属性保留 :通过 partial 创建的新函数会保留原函数的一些属性

    • 像 __name__ 和 __doc__ 等函数属性还在

附录:与 Lambda 表达式的对比

使用 partial 和 lambda 都能实现参数固定的效果,但它们之间也有区别:

1
2
3
4
5
# 使用 partial
add_ten = partial(add, 10)

# 使用 lambda
add_ten_lambda = lambda x: add(10, x)
  • partial 函数在代码简洁性上表现更优,并且能够保留原函数的元信息
  • lambda 表达式则更为灵活,可以实现更复杂的逻辑

Python-Jupyter——配置跨机器使用

Jupyter notebook默认是不能跨机器使用的,只能使用localhost访问,本文讲述了让其能跨机器访问的方法


Jupyter notebook跨机器使用配置说明

生成配置文件

1
jupyter notebook --generate-config
* 如果是`root`用户可能会存在问题,按照提示操作即可

生成密码

1
jupyter notebook password
* 按照提示输入密码,这就是以后在远程访问时使用的密码
* 生成的秘钥在`~/.jupyter/jupyter_notebook_config.json`下

修改配置文件

1
vim  jupyter_notebook_config.py
  • 需要修改以下行
    1
    2
    3
    4
    c.NotebookApp.ip='*' # 这里可以写成本机的公网ip,或者是局域网ip
    c.NotebookApp.password = u'sha1:***' # 这里需要复制修改成刚才生成的密文
    c.NotebookApp.open_browser = False # 启动Jupyter时是否自动打开Web页面
    c.NotebookApp.port =8888 #可自行指定一个端口, 访问时使用该端口

Linux——Logstash时区问题

有时候Linux系统重启或者有修改后会造成时区被修改,默认一般是UTC时间,有时候会变成CST时间
在阿里云主机扩展后出现过一次,造成了Logstash 使用JDBC连接数据库时读取报错:大概是JavaLang::IllegalArgumentException: HOUR_OF_DAY: 2 -> 3这样的错


解决方案:

改系统时区

  • 将系统的时区改回去,然后重启
    1
    2
    3
    4
    # 修改时区命令:	
    timedatectl set-timezone UTC
    # 重启命令:
    shutdown -r now

重启后继续运行之前出错的程序,成功解决问题

链接时加参数

  • 在连接mysql-connector时加上一个时区参数

  • 以logstash为例子

    • 在mysql.config中修改连接语句原来为(连接到名称为”docker“的数据库,但是没有指定参数)

      1
      jdbc:mysql://localhost:3306/docker
    • 修改后连接语句为(制定参数为UTC)

      1
      jdbc:mysql://localhost:3306/docker?serverTimezone=UTC

注意,这种方式修改后我的系统时区可为任意的,比如我的系统时区就一直为CST

替换JDBC版本【未测试】

  • 网上有博客指出可以通过换jdbc connector的版本解决问题

Linux——exec命令的使用


整体说明

  • Linux Shell 脚本中,exec 命令用于在当前 shell 进程中执行指定的命令,而不是启动一个新的子进程

  • exec 常常用来替换当前 shell 进程,或者重定向文件描述符

  • exec 基本语法如下:

    1
    exec 命令 [参数...]
    • 执行后,当前 shell 进程会被新命令替换,原 shell 脚本后续的内容将不会再执行

exec 替换进程用法

  • 假如在脚本中写:

    1
    2
    3
    4
    #!/bin/bash
    echo "Before exec"
    exec ls -l
    echo "After exec"
    • 输出只会有 “Before exec” 和 ls -l 的结果,而不会有 “After exec”,因为 exec ls -l 之后,脚本所在的 shell 进程已经被 ls 取代,后续语句不会执行

exec 实现文件描述符重定向

  • exec 也常用于重定向输入输出,不会启动新进程,而是改变当前 shell 的文件描述符。例如:

    • 将标准输出重定向到文件:

      1
      2
      exec > output.txt
      echo "This will go to output.txt"
      • 这样,后续所有标准输出都会写入 output.txt 文件
    • 将标准输入重定向为某个文件:

      1
      2
      3
      exec < input.txt
      read line
      echo $line
      • 这样,read 命令会从 input.txt 读取内容
    • 关闭文件描述符:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      # 打开一个文件用于读取,赋予文件描述符3
      exec 3< myfile.txt

      # 通过文件描述符3读取一行
      read line <&3
      echo "读取到的内容: $line"

      # 关闭文件描述符3
      exec 3<&-
      • 这表示关闭文件描述符 3

Linux——alias功能使用


整体说明

  • 命令别名(alias)是为复杂命令或命令组合创建的“快捷方式”
  • 可以减少重复输入,提高效率

创建别名

  • 别名创建命令

    1
    alias 别名="原命令"
  • 常用别名举例:

    1
    2
    # 创建 ll 别名,替代 ls -l
    alias ll='ls -l'
  • 创建别名后,直接使用别名即可实现与原命令同等效果

    1
    2
    # 输入 ll,相当于执行 ls -l
    ll

别名管理

  • 别名管理命令:
    1
    2
    3
    4
    5
    6
    7
    8
    # 查看所有别名
    alias

    # 查看某个别名的定义
    alias ll

    # 删除 ll 别名
    unalias ll

别名永久生效

  • 以上命令创建的别名是临时的,重新启动终端后会消失,为了长久保留别名,可通过修改配置文件实现

  • 编辑配置文件 :

    1
    2
    3
    4
    5
    # 用 vim 打开配置文件(适用于 bash 终端)
    vim ~/.bashrc

    # 如果你使用的是 zsh 终端,则打开
    vim ~/.zshrc
  • 添加别名定义(在文件末尾添加类似以下内容:):

    1
    2
    3
    4
    5
    6
    7
    8
    # 常用文件列表别名
    alias ll='ls -l'
    alias la='ls -a'
    alias lla='ls -la'

    # 系统管理别名
    alias update='sudo apt update && sudo apt upgrade -y'
    alias reboot='sudo reboot'

附录:常见通用实用别名实践

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 安全删除(删除前询问确认)
alias rm='rm -i'

# 带颜色的 grep
alias grep='grep --color=auto'

# 快速回到上级目录
alias ..='cd ..'

# 查看网络连接
alias net='netstat -tulpn'

# 查看磁盘使用情况
alias df='df -h'

# ll 替代 ls -l
alias ll='ls -l'

附录:其他注意点

  • 单引号 ':不解析变量,适合直接替换命令

  • 双引号 ":会解析变量,适合需要动态内容的别名(不常用)

  • 别名优先级高于原始命令,若要执行原始命令,可使用 \[原命令名](比如 \ls)

    1
    \命令名  # 例如:\ls
  • 不要使用系统已有命令作为别名,否则会覆盖原命令

Linux——find命令详解

本文介绍Linux下find命令的使用方法

  • 参考博客: https://www.cnblogs.com/weijiangbao/p/7653588.html

常用方法说明

  • find命令用于在给定目录下查找符合给定条件的文件

  • 用法:

    1
    Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
  • 常用的用法:

    1
    2
    find   path   -option   [   -print ]   [ -exec   -ok   command ]   {} \;
    find 目标目录 选项 查找完成后执行的操作
  • 实例1:

    1
    find . -name "*a*.py" -exec cat {} \; | grep test
    • 解析:将当前文件夹下的名字能匹配*a*.py的文件找出来,并输出其中含有”test”的行
      • .对应path参数,代表搜索路径为当前文件夹, 默认会递归搜索
      • -name "*a*.py"对应选项,指出找文件的筛选条件
      • -exec cat {} \; | grep test指明找到文件后需要执行的操作,{}用于表示前面被固定下来的接受参数, 由于{}后面必须使用分号;,而命令行中分号需要转义字符转义,所以就是\;
        • 注意: 这里{} \;中间必须空一格,且{} \;中间不能加任何字符或命令等
  • 示例2:

    1
    find . -maxdepth 1 -name "test*.py" -exec cat {} \;| grep test
    • 在前面的基础上指定只从第一层目录中查找,不递归

参数和选项详解

1
find   path   -option   [   -print ]   [ -exec   -ok   command ]   {} \;

参数

  • -print: find命令将匹配的文件输出到标准输出
  • -exec: find命令对匹配的文件执行该参数所给出的shell命令。相应命令的形式为’command’ { } ;,注意{ }和;之间的空格
  • -ok: 和-exec的作用相同,只不过以一种更为安全的模式来执行该参数所给出的shell命令,在执行每一个命令之前,都会给出提示,让用户来确定是否执行

选项

  • -name: 按照文件名查找文件
  • -perm: 按照文件权限来查找文件
  • -prune: 使用这一选项可以使find命令不在当前指定的目录中查找,如果同时使用-depth选项,那么-prune将被find命令忽略
  • -user: 按照文件属主来查找文件
  • -group: 按照文件所属的组来查找文件
  • -mtime -n +n: 按照文件的更改时间来查找文件, - n表示文件更改时间距现在n天以内,+ n表示文件更改时间距现在n天以前。find命令还有-atime和-ctime 选项,但它们都和-m time选项
  • -nogroup: 查找无有效所属组的文件,即该文件所属的组在/etc/groups中不存在
  • -nouser: 查找无有效属主的文件,即该文件的属主在/etc/passwd中不存在
  • -newer file1 ! file2: 查找更改时间比文件file1新但比文件file2旧的文件
  • -type: 查找某一类型的文件
    • 默认是查找所有类型
参数 文件类型
d 目录
c 字符设备文件
p 管道文件
f 普通文件
l 符号链接文件
b 块设备文件
1…394041…61
Joe Zhou

Joe Zhou

Stay Hungry. Stay Foolish.

608 posts
49 tags
GitHub E-Mail
© 2026 Joe Zhou
Powered by Hexo
|
Theme — NexT.Gemini v5.1.4