标签: python

  • pandas的index

    • 定义index
      1. 读取csv时
        data = pd.read_csv('data.csv', index_col='id')
        这种方法会创建命名的索引列,并且会放在第1列(不管csv文件中是第几列)
      2. 声明DataFrame时
        data = [['Google', 10], ['Runoob', 12], ['Wiki', 13], ['Baidu', 20], ['taobao', 15]]
        # 创建DataFrame
        df = pd.DataFrame(data, columns=['Site', 'Age'], index=[1,2,3,4,6])
        

        这种方法会创建没有名字的索引列,仍然放在第1列。

    • 遍历时使用index
      1. 使有iterrows()
        for index, item in df.iterrows():
        print(index, item) #index的值就是上述定义的index值,并不是连续的序号
        print(item[0]) #item[0]就是第1列Site的值,item中不包含index列
        
      2. 使用itertuples()
        for item in df.itertuples():
        print(item)
        print(item.Index) # i.Index就是索引列的值
        print(item[0]) # 与item.Index的值相同,也是id列的值,id列会强制移动第0列。
        print(item[1]) # Site列的值
        

        如果原始数据中没有index会自动生成一个递增的index列。

      3. 无index的itertuples()
        for item in df.itertuples(index=False):
        print(item)
        #print(item.Index) # 报错
        print(item[0]) # Site列的值
        print(item[1]) # Age列的址
        

        id列或者index列会被从Series中移除,无法访问id列。

    Views: 0

  • pyinstaller报dateutil\zoneinfo\__init__.py:36: UserWarning: I/O error(2): No such file or directory

    pyinstaller -F --collect-all dateutil

    参考:
    https://stackoverflow.com/questions/76319779/unable-to-get-timezone-information-in-pyinstaller-executable

    Views: 2

  • python关于全局变量之变量遮蔽

    全局变量在主程序和模块中的行为是不一样的
    – 模块中
    在函数中无论是否使用global声明,都可以通过赋值改变全局变量
    – 主文件中
    如果有global声明则可以通过赋值改变全局变量,但是没有global声明时在函数中无法通过赋值改变全局变量而是创建一个新的局部变量,全局变量中的内容不会改变,但是又可以直接引用全局变量的内容。也就是说读的时候是全局变量,一旦写入就变成了局部变量,这种行为还有一个名词叫变量遮蔽(https://zh.wikipedia.org/wiki/%E8%AE%8A%E6%95%B8%E9%81%AE%E8%94%BD)。
    总结就是除了在主文件中使用global时没有变量遮蔽,其它情况下都会存在遮蔽。

    Views: 6

  • python使用协程循环并发执行http请求

    import asyncio
    import aiohttp
    
    async def do_request(val):
        timeout = aiohttp.ClientTimeout(total=86400)
        async with aiohttp.ClientSession(timeout=timeout) as session:
            async with session.post('http://127.0.0.1:5000'), json={"val": val}) as resp:
            result = await resp.json()
            return result
    
        async def main(count):
            tasks = [do_request(val) from val in range(count)]
            values = await asyncio.gather(*tasks)
            print(values)
    
    asyncio.run(main(10))
    

    参考:
    https://superfastpython.com/asyncio-for-loop/
    https://www.dongwm.com/post/understand-asyncio-1/
    https://www.dongwm.com/post/understand-asyncio-2/

    Views: 2

  • 用Cython把Python模块转换为纯C语言模块

    转换为C语言模块后可以与Python解释器编译到一起作为内置模块用,也可以外部模块import后使用。

    1. 创建嵌入式模块

    嵌入式模块可以嵌入到独立C语言程序中执行
    首先编写普通的python模块代码,然后在python代码的基础上创建pyx代码,通过cdef声明可以定义原生C语言函数,而不用通过Python解释器调用,可以更好的与C语言交互。
    pyx代码的写法可以参考cython官方文档
    hello.pyx文件

    cdef public char *say_hello_to(char* name):
        return name
    

    c-test.c文件

    #include "Python.h"
    #include "hello.h"
    int main(int argc, char *argv[])
    {
        PyObject *pmodule;
        char *result;
        wchar_t *program;
    
       // 读取命令行参数
        program = Py_DecodeLocale(argv[0], NULL);
        if (program == NULL) {
            fprintf(stderr, "Fatal error: cannot decode argv[0], got %d arguments\n", argc);
            exit(1);
        }
        /* 把模块注册为内置模块 */
    
        if (PyImport_AppendInittab("test", PyInit_hello) == -1) {
    
            fprintf(stderr, "Error: could not extend in-built modules table\n");
    
            exit(1);
    
        }
        /* 把命令行参数传给Python解释器 */
        Py_SetProgramName(program);
    
        /* 初始化Python,这一步是必须的. */
        Py_Initialize();
    
        /* 调用Python中的函数. */
        result = say_hello_to("hetao");
        // PyErr_Print();
        printf("result:%s\n", result);
    
          /* Clean up after using CPython. */
        PyMem_RawFree(program);
        Py_FinalizeEx();
    
        return 0;
    
        /* Clean up in the error cases above. */
    exit_with_error:
        PyMem_RawFree(program);
        Py_Finalize();
        return 1;
    }
    

    cython hello.pyx --3str
    执行cython后会生成hello.c和hello.h两个文件

    gcc -o libhello.so -shared  -fPIC -I/usr/include/python3.10 hello.c
    gcc -o test-c -I/usr/include/python3.10 -I./ -L./ -ltest -lpython3.10 -Wl,-rpath . test-c.c
    

    运行结果

    $ ./test-c
    result:hetao

    2. 创建外部模块

    hello.pyx文件

    def say_hello_to(name):
        return name
    

    setup.py文件

    from setuptools import setup
    from Cython.Build import cythonize
    
    setup(
        name='Hello',
        ext_modules=cythonize("hello.pyx"),
    )
    

    构建模块
    python setup.py build_ext --inplace

    test-hello.py文件

    import hello
    
    result = hello.say_hello_to("hetao")
    print(result)
    

    cdef、def 和 cpdef 的区别:

    在 Cython 中,有三种不同的函数声明方式:cdef、def 和 cpdef。
    cdef 声明的函数是纯 C 函数,只能从 Cython 代码中调用,不可从 Python 代码中访问。
    def 声明的函数是 Python 函数,可以从 Python 代码中调用,但会带来一些性能开销。
    cpdef 声明的函数是混合函数,既可以从 Cython 代码中调用,也可以从 Python 代码中调用,其底层其实生成了两个函数版本。

    关于编译参数:

    获取编译参数
    python3-config –cflags
    获取链接参数
    python3-config –ldflags

    Views: 1

  • C语言调用Python模块中的Python函数

    #include "Python.h"
    int main()
    {
            Py_Initialize();
            PyObject *pmodule = PyImport_ImportModule("os");
            //获取当前用户的id
            PyObject *pfunc = PyObject_GetAttrString(pmodule, "geteuid");
            PyObject *arg = Py_BuildValue("()");
            PyObject *result = PyObject_Call(pfunc, arg, NULL);
            long retval = PyLong_AsLong(result);
            printf("result: %ld\n", retval);
            Py_XDECREF(result);
            Py_FinalizeEx();
            return 0;
    }
    
    gcc -c -I/usr/include/python3.10  -L/usr/lib/python3.10/config-3.10-x86_64-linux-gnu -L/usr/lib/x86_64-linux-gnu -lpython3.10 -lcrypt -ldl  -lm -lm  test.c
    gcc -o test test.o  -L/usr/lib/python3.10/config-3.10-x86_64-linux-gnu -L/usr/lib/x86_64-linux-gnu -lpython3.10 -lcrypt -ldl  -lm
    

    执行后返回如下:

    $ ./test
    result: 1001
    这种方法可以调用普通Python函数

    Views: 1

  • C语言调用Python模块中的C函数

    C语言写的Python模块中可以有python函数,也可以有C函数。
    以下代码导入Python模块并执行其中的C函数
    ctest.c文件内容

    #include "Python.h"
    #include "test.h"
     int main(int argc, char *argv[])
    {
        PyObject *pmodule;
        int *result;
        wchar_t *program;
    
       // 读取命令行参数
        program = Py_DecodeLocale(argv[0], NULL);
        if (program == NULL) {
            fprintf(stderr, "Fatal error: cannot decode argv[0], got %d arguments\n", argc);
            exit(1);
        }
        /* 把模块注册为内置模块 */
    
        if (PyImport_AppendInittab("test", PyInit_test) == -1) {
    
            fprintf(stderr, "Error: could not extend in-built modules table\n");
    
            exit(1);
    
        }
        /* 把命令行参数传给Python解释器 */
        Py_SetProgramName(program);
    
        /* 初始化Python,这一步是必须的. */
        Py_Initialize();
    
        /* 调用Python中的函数. */
        result = hello(1, 2);
        // PyErr_Print();
        printf("result:%d,%d,%lu\n", result[0], result[2], sizeof(result));
    
          /* Clean up after using CPython. */
        PyMem_RawFree(program);
        Py_FinalizeEx();
    
        return 0;
    
        /* Clean up in the error cases above. */
    exit_with_error:
        PyMem_RawFree(program);
        Py_Finalize();
        return 1;
    }
    

    编译

    gcc -o ctest -I/usr/include/python3.10 -I./ -L./ -ltest -lpython3.10 -Wl,-rpath . ctest.c
    

    如果是调用python自带的内置函数则不需要执行PyImport_AppendInittab,直接调用即可。
    只有C语言写的模块才能注册为内置模块

    关于Python解释器初始化的问题:
    cython官方文档上说如果不调用Py_Initialize()进行初始化极有可能会发生程序崩溃,但并没有说明什么情况下会崩溃。经过我的测试如果所调用的C函数不涉及Python代码,也不会调用其它可能会执行Python代码的函数则不会崩溃,反之就会发生断错误。也就是说只能在C语言的内存空间内执行。对于一些Python内置的C语言写的函数是可以不初始化就调用的,如果是那种需要import的就不可以了。

    Views: 1

  • Python数据等比连续抽样算法

    numpy里面自带了几种抽样算法,但都是随机抽样,我这里要做的是等比连续抽样,就是对原始数据从前到后按固定的间隔固定的顺序去抽样数据。
    方法一:
    把列表分成n个子组,从每个子组中再抽取一个数作为样本

    def evenly_divide_list(lst, num_groups):
        """按顺序分隔列表为指定数量的子组
        Args:
            lst (list): 列表
            num_groups (int): 分隔次数
        Returns:
            list: 返回子列表的集合
        """
        quotient, remainder = divmod(len(lst), num_groups)
        group_sizes = [quotient] * num_groups
        for i in range(remainder):
            group_sizes[i] += 1
        groups = []
        i = 0
        for size in group_sizes:
            groups.append(lst[i:i + size])
            i += size
        return groups
    data = [1, 2, 4, 5]
    count = 3
    sample_group = evenly_divide_list(data, count)
    for i in range(len(sample_group)):
            print(sample_group[i][0])
    

    方法二:
    对列表索引分成固定的间隔然后进行进行四舍五入

    def extract_elements(lst, num_elements):
        """按顺序均匀抽样元素
        Args:
            lst (list): 列表
            num_groups (int): 抽样次数
        Returns:
            list: 返回抽样元素的集合
        """
        if num_elements > len(lst):
            return lst
        step = len(lst) / num_elements
        return [lst[round(i * step)] for i in range(num_elements)]
    data = [1, 2, 4, 5]
    count = 3
    sample_group = extract_elements(data, count)
    for i in range(len(sample_group)):
            print(sample_group[i])
    

    第一种方法是把不能整分的元素全部加到最前面几个组中,这样前面的组就比后面的组抽样间隔更大
    第二种方法则是把不能等分的元素按四舍五入法分散在不同的段中,这种方法显然抽样更均匀,而且方法一多了一个数组切分过程,算法复杂度更大,所以推荐用方法二。

    Views: 2

  • 正态分布及Python用法

    方差和标准差都是用来反映样本差异大小的
    方差的计算公式:

    标准差的计算公式:
    标准差就是方差的开平方,求方差的目的就是为了得到标准差,方差是求标准差过程的中间值。数学符号是:σ
    正态分布的计算公式:

    其中只有两个变量,一个是中间值,也就是总体的平均值,样本均数,总值均值,用mean表示,数学符号是μ。另一个值就是方差(这里用方差不用标准差应该只是计算方便),数学符号是

    Python用numpy生成符合正态分布的随机数:
    random.normal(loc=0.0, scale=1.0, size=None)
    loc就是中间值,scale是标准差,szie是数据结构,如果整数就是生成几条数据,如果元组就是就数组的维数

    Views: 27

  • Centos7安装Python12

    centos7自带的gcc和openssl版本过低无法成功编译python3.12,所以需要另外安装gcc11和编译openssl1.11。

    yum install centos-release-scl
    yum install -y devtoolset-11-gcc devtoolset-11-gcc-c++
    scl enable devtoolset-11 bash
    echo /opt/rh/devtoolset-11/root/usr/bin/gcc>>~/.bashrc
    yum install -y wget make cmake gcc bzip2-devel libffi-devel zlib-devel
    yum groupinstall -y "Development Tools"
    wget https://www.openssl.org/source/old/1.1.1/openssl-1.1.1w.tar.gz
    tar -zxf openssl-1.1.1w.tar.gz
    cd openssl-1.1.1w
    ./config --prefix=/usr/local/openssl --openssldir=/usr/local/openssl
    make && make install_sw
    export PATH=/usr/local/openssl/bin:\PATH
    export LD_LIBRARY_PATH=/usr/local/openssl/lib:\$LD_LIBRARY_PATH
    cd ..
    wget https://www.python.org/ftp/python/3.12.3/Python-3.12.3.tgz
    tar -zxf Python-3.12.3.tgz
    cd Python-3.12.3
    ./configure --with-openssl=/usr/local/python3 --enable-shared --enable-optimizations
    CFLAGS=-Wno-coverage-mismatch make
    make install
    export PATH=/usr/local/python3/bin:PATH
    export LD_LIBRARY_PATH=/usr/local/python3/lib:$LD_LIBRARY_PATH
    echo /usr/local/python3/lib/ > /etc/ld.so.conf.d/python.conf
    ldconfig
    

    Views: 14