【问题标题】:Use Map function with subsets of a pandas series or dataframe将 Map 函数与 pandas 系列或数据框的子集一起使用
【发布时间】:2017-10-23 13:52:19
【问题描述】:

假设我有一个 pandas.Dataframe,如下所示:

c1 | c2
-------
 1 | 5 
 2 | 6 
 3 | 7 
 4 | 8
 .....
 1 | 7

我希望映射一个函数 (DataFrame.corr),但我希望它一次占用 n 行。结果应该是一个序列,其相关值比原始 DataFrame 短,或者有一些值没有得到完整的n 数据行。

有没有办法做到这一点以及如何做到这一点?我一直在查看 DataFrame 和 Map、Apply、Filter 文档,但似乎没有明显或干净的解决方案。

【问题讨论】:

    标签: python python-3.x pandas dataframe apply


    【解决方案1】:

    对于 pandas 0.20,使用 rollingcorr 会生成一个多索引数据帧。您可以在之后切片以获取您要查找的内容。

    考虑数据框df

    np.random.seed([3,1415])
    df = pd.DataFrame(np.random.randint(10, size=(10, 2)), columns=['c1', 'c2'])
    
       c1  c2
    0   0   2
    1   7   3
    2   8   7
    3   0   6
    4   8   6
    5   0   2
    6   0   4
    7   9   7
    8   3   2
    9   4   3
    

    rolling + corr...pandas 0.20.x

    df.rolling(5).corr().dropna().c1.xs('c2', level=1)
    # Or equivalently
    # df.rolling(5).corr().stack().xs(['c1', 'c2'], level=[1, 2])
    
    4    0.399056
    5    0.399056
    6    0.684653
    7    0.696074
    8    0.841136
    9    0.762187
    Name: c1, dtype: float64
    

    rolling + corr...pandas 0.19.x 或之前
    在 0.20 之前,rolling + corr 产生了 pd.Panel

    df.rolling(5).corr().loc[:, 'c1', 'c2'].dropna()
    
    4    0.399056
    5    0.399056
    6    0.684653
    7    0.696074
    8    0.841136
    9    0.762187
    Name: c2, dtype: float64
    

    numpy + as_strided
    但是,我对上面的答案并不满意。下面是一个专门的函数,它采用 nx2 数据帧并返回一系列滚动相关性。 免责声明 这使用了一些高级技术,并且只有在您知道它的作用时才应该使用。这意味着如果您需要详细了解其工作原理......那么它可能不适合您。

    from numpy.lib.stride_tricks import as_strided as strided
    
    def rolling_correlation(a, w):
        n, m = a.shape[0], 2
        s1, s2 = a.strides
        b = strided(a, (m, w, n - w + 1), (s2, s1, s1))
        b_mb = b - b.mean(1, keepdims=True)
        b_ss = (b_mb ** 2).sum(1) ** .5
        return (b_mb[0] * b_mb[1]).sum(0) / (b_ss[0] * b_ss[1])
    
    def rolling_correlation_df(df, w):
        a = df.values
        return pd.Series(rolling_correlation(a, w), df.index[w-1:])
    
    rolling_correlation_df(df, 5)
    
    4    0.399056
    5    0.399056
    6    0.684653
    7    0.696074
    8    0.841136
    9    0.762187
    dtype: float64
    

    时机
    小数据

    %timeit rolling_correlation_df(df, 5)
    10000 loops, best of 3: 79.9 µs per loop
    
    %timeit df.rolling(5).corr().stack().xs(['c1', 'c2'], level=[1, 2])
    100 loops, best of 3: 14.6 ms per loop
    

    大数据

    np.random.seed([3,1415])
    df = pd.DataFrame(np.random.randint(10, size=(10000, 2)), columns=['c1', 'c2'])
    
    %timeit rolling_correlation_df(df, 5)
    1000 loops, best of 3: 615 µs per loop
    
    %timeit df.rolling(5).corr().stack().xs(['c1', 'c2'], level=[1, 2])
    1 loop, best of 3: 1.98 s per loop
    

    【讨论】:

    • 这正是我想要的!!谢谢
    猜你喜欢
    • 2018-11-22
    • 1970-01-01
    • 2016-05-12
    • 1970-01-01
    • 2019-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-01
    相关资源
    最近更新 更多