对智谱清言有点失望 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
NoOneNoBody
V2EX    OpenAI

对智谱清言有点失望

  •  
  •   NoOneNoBody 2024-02-15 16:06:58 +08:00 1728 次点击
    这是一个创建于 682 天前的主题,其中的信息可能已经有所发展或是发生改变。

    GLM-4 首先,它不知道“智谱清言”是什么,哈哈

    “有一个 dataframe ,index 为整数,已经排序,所有值均为浮点类型,求其中两列,假设名为 a,b ,它们是否相交,a 上穿 b 为 1 ,a 下穿 b 为-1 ,无相交为 0 ,返回一个 series ,使用 Numba 加速” 这段话,chatgpt3.5 给我的是代码,智谱清言给我的是计算结果……结果,就是它自己生成了一个 datframe 并计算了,把结果回答给我,很晕

    chatgp3.5 虽然给我的代码是错的,但受它启发,写了个简单函数完成了,这个函数是向量化的

    def is_cross(arr:np.ndarray, arr_ref:np.ndarray)->np.ndarray: ''' 求两个 array 是否有相交\n 返回:一个 numpy array\n 其中 0 表示没有相交,1 表示 arr 上穿 arr_ref ,-1 则表示下穿\n \n 原理:求两个 array 的差并获取符号数列,求取这个符号数列相邻的差,再次获取这个差值数列的符号为返回结果\n 相邻符号如果相同差为 0 ,就是无相交;符号从-变 0/+,为上穿,差值为+1/+2 ;符号从+变 0/-,为下穿,差值为-1/-2\n 符号从 0 变为有符号,性质一样,结果也符合需求\n 所以再次求取符号则为结果 ''' return np.sign(np.ediff1d(np.sign(arr-arr_ref), to_begin=0)) 
    2 条回复    2024-02-17 01:40:28 +08:00
    cwyalpha
        1
    cwyalpha  
       2024-02-16 14:54:32 +08:00 via iPhone
    要解决这个问题,我们可以编写一个 Python 函数,该函数接受一个 DataFrame 和两列名作为输入,并返回一个 Series ,表示列`a`和列`b`的穿越情况。然后,我们将使用 Numba 装饰器`@jit`来加速这个函数。

    1. **定义函数**:函数将遍历 DataFrame 的行,比较每一行的`a`和`b`列值与其上一行的值,以确定是否发生了上穿或下穿。
    2. **使用 Numba 加速**:通过在函数定义前添加`@jit`装饰器来加速函数。Numba 是一个开源的 JIT ( Just-In-Time )编译器,它可以显著提高 Python 代码的执行速度,特别是对于数值计算和科学计算非常有效。
    3. **返回 Series**:根据穿越情况,为每个时间点返回 1 (上穿)、-1 (下穿)或 0 (无相交)。

    下面是实现这个逻辑的代码示例。首先,确保你已经安装了`numba`和`pandas`库。

    ```python
    import pandas as pd
    import numpy as np
    from numba import jit

    # 示例 DataFrame 创建,仅供参考
    # df = pd.DataFrame({'a': np.random.rand(10), 'b': np.random.rand(10)})

    @jit(nopython=True)
    def calculate_cross_over(a, b):
    result = np.zeros(len(a))
    for i in range(1, len(a)):
    if a[i] > b[i] and a[i-1] <= b[i-1]:
    result[i] = 1 # a 上穿 b
    elif a[i] < b[i] and a[i-1] >= b[i-1]:
    result[i] = -1 # a 下穿 b
    # 其他情况默认为 0 ,无需额外处理
    return result

    def cross_over_series(df, col_a, col_b):
    a_values = df[col_a].values
    b_values = df[col_b].values
    cross_over_values = calculate_cross_over(a_values, b_values)
    return pd.Series(cross_over_values, index=df.index)

    # 使用函数的示例
    # result_series = cross_over_series(df, 'a', 'b')
    # print(result_series)
    ```

    在这个代码中:
    - `calculate_cross_over`函数是使用 Numba JIT 编译的核心函数,它负责计算两列之间的穿越情况。
    - `cross_over_series`函数是一个封装函数,它接受 DataFrame 和列名作为输入,调用`calculate_cross_over`函数,并返回结果 Series 。

    请注意,由于 Numba 的`nopython`模式限制,我们直接在 Numba 函数中使用了 Numpy 数组而不是直接操作 DataFrame 。这是因为 Numba 最优化地支持 Numpy 数组计算。




    -------
    能否向量化地完成这个代码
    -------


    向量化的方法可以使用 Pandas 和 Numpy 的内置功能来实现,而不需要显式循环,这样可以提高计算效率并简化代码。下面是如何使用向量化方法来完成相交点检测的步骤:

    1. **计算差分**:首先,计算两列`a`和`b`的差分,即`a - b`。这将用于确定`a`是否在`b`之上或之下。
    2. **标记穿越点**:通过比较相邻元素的差分符号,我们可以找到穿越点。当差分从负变正时,表示`a`上穿`b`;从正变负时,表示`a`下穿`b`。
    3. **返回 Series**:最终,我们将创建一个 Series ,根据是否发生穿越以及穿越的方向来分配值( 1 代表上穿,-1 代表下穿,0 代表无穿越)。

    下面是实现这个方法的代码示例:

    ```python
    import pandas as pd
    import numpy as np

    def vectorized_cross_over(df, col_a, col_b):
    # 计算 a 和 b 的差值
    diff = df[col_a] - df[col_b]
    # 计算差值的符号变化(正负变化),使用 np.sign(diff)获取符号,并通过 diff 计算其差分以检测变化
    sign_changes = np.sign(diff).diff()

    # 上穿为 1 ,下穿为-1 ,无穿越为 0
    # np.sign(diff).diff() == 2 表示从负到正的变化,即上穿
    # np.sign(diff).diff() == -2 表示从正到负的变化,即下穿
    crossover_series = pd.Series(0, index=df.index) # 初始化为 0
    crossover_series[sign_changes == 2] = 1 # 上穿
    crossover_series[sign_changes == -2] = -1 # 下穿

    return crossover_series

    # 示例 DataFrame 创建
    # df = pd.DataFrame({'a': np.random.rand(10), 'b': np.random.rand(10)})

    # 使用函数
    # result_series = vectorized_cross_over(df, 'a', 'b')
    # print(result_series)
    ```

    这段代码完全使用向量化操作来检测`a`和`b`列的穿越情况,避免了显式循环,从而提高了性能。需要注意的是,由于使用了`diff()`方法,第一个元素将总是被标记为 0 (无穿越),因为它没有前一个元素来比较。







    GPT4 的回答不知道是否正确
    NoOneNoBody
        2
    NoOneNoBody  
    OP
       2024-02-17 01:40:28 +08:00
    @cwyalpha #1
    原理是一样的,np.ediff1d 和 pd.Series.diff 是一样的,只是 np.ediff1d 计算少了第一个值,补个 to_begin=0 参数而已
    我起初也是用 diff(),后来才改成兼容性更高的 numpy

    不过这里 gpt 漏了一个逻辑,相邻两个其中一个是 0 ,另一个是+1/-1 ,这个 diff 结果是+1 或-1 ,不是+2/-2
    用==2/==-2 会漏掉这个
    0 就是两条线在同一个点刚好相等的情况,如 a=[1,2,3,4], b=[3,2,1,0],第二个点是刚好相等的
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2884 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 13:17 PVG 21:17 LAX 05:17 JFK 08:17
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86