【问题标题】:How to convert a particular dataframe into a series by combining columns如何通过组合列将特定数据框转换为系列
【发布时间】:2020-05-17 02:32:51
【问题描述】:

给定以下数据,其中3 表示yes2 表示no

t = pd.DataFrame({"v_1": [2, 2, 3], "v_2": [2, 3, 2], "v_3": [3, 2, 2],})

看起来像

   v_1  v_2  v_3
0    2    2    3
1    2    3    2
2    3    2    2

我想创建以下系列

0    v_3
1    v_2
2    v_1

我想到的只有以下几点:

t['V'] = t.sum().reset_index(drop=True)

给了

   v_1  v_2  v_3    V
0            v_3  v_1
1       v_2       v_2
2  v_1            v_3

我想知道是否有比这更好的方法,或者更通用的方法。

【问题讨论】:

  • 你只想要一系列的列?
  • @sammywemmy 本质上 - 每列当前代表一个级别,因此它基本上是一次性编码的。而且我希望能够将其转换为单列,而不是分散到许多列中。

标签: python pandas data-manipulation


【解决方案1】:

也许这就是你需要的,以保持 3s 并将它们连接成一个系列?

(
    t.apply(lambda x: np.where(x.eq(3), x.name, None))
    .stack().reset_index(drop=True)
)

0    v_3
1    v_2
2    v_1
dtype: object

【讨论】:

    【解决方案2】:

    试一试:

    (t
     .stack()
     .droplevel(0)
     .loc[lambda x: x.eq(3)]
     .reset_index(name='temp')
     .drop('temp',axis=1)
     )
    
        index
    0   v_3
    1   v_2
    2   v_1
    

    【讨论】:

      【解决方案3】:

      使用DataFrame.where 将非3 值替换为缺失值,然后通过DataFrame.stack 重塑,删除MultiIndex 的第一级并最后从index 创建Series(如果性能很重要):

      s = pd.Series(t.where(t.eq(3)).stack().droplevel(0).index)
      #alternative
      #s = pd.Series(t.where(t.eq(3)).stack().reset_index(0, drop=True).index)
      print (s)
      0    v_3
      1    v_2
      2    v_1
      dtype: object
      

      详情

      print (t.where(t.eq(3)))
         v_1  v_2  v_3
      0  NaN  NaN  3.0
      1  NaN  3.0  NaN
      2  3.0  NaN  NaN
      print (t.where(t.eq(3)).stack())
      0  v_3    3.0
      1  v_2    3.0
      2  v_1    3.0
      dtype: float64
      print (t.where(t.eq(3)).stack().droplevel(0))
      v_3    3.0
      v_2    3.0
      v_1    3.0
      dtype: float64
      

      1k 行 10 列的性能:

      np.random.seed(123)
      
      t = pd.DataFrame(np.random.choice([2,3], (1000, 10))).add_prefix('v_')
      #print (t)
      
      In [25]: %timeit pd.Series(t.where(t.eq(3)).stack().droplevel(0).index)
      2.66 ms ± 93.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
      
      In [26]: %timeit pd.Series(t.where(t.eq(3)).stack().reset_index(0, drop=True).index)
      2.61 ms ± 41.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
      
      In [27]: %timeit t.apply(lambda x: np.where(x.eq(3), x.name, None)).stack().reset_index(drop=True)
      5.98 ms ± 46.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
      
      In [28]: %timeit t.stack().droplevel(0).loc[lambda x: x.eq(3)].reset_index(name='temp').drop('temp',axis=1)
      3.48 ms ± 36.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
      

      100k 行和 10 列的性能:

      t = pd.DataFrame(np.random.choice([2,3], (100000, 10))).add_prefix('v_')
      print (t)
      In [30]: %timeit pd.Series(t.where(t.eq(3)).stack().droplevel(0).index)
      84.7 ms ± 1.41 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
      
      In [31]: %timeit pd.Series(t.where(t.eq(3)).stack().reset_index(0, drop=True).index)
      84.1 ms ± 459 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
      
      In [32]: %timeit t.apply(lambda x: np.where(x.eq(3), x.name, None)).stack().reset_index(drop=True)
      147 ms ± 688 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
      
      In [33]: %timeit t.stack().droplevel(0).loc[lambda x: x.eq(3)].reset_index(name='temp').drop('temp',axis=1)
      101 ms ± 635 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
      

      【讨论】:

        【解决方案4】:

        您可以为每列创建一个位置为 3 的新索引。然后将该索引应用于列名。

        import pandas as pd
        t = pd.DataFrame({"v_1": [2, 2, 3], "v_2": [2, 3, 2], "v_3": [3, 2, 2],})
        
        index_list = [t[t[col]==3].index[0] for col in t.columns] # create new index
        series = pd.Series(t.columns) # series of column names
        series.index = index_list # apply index to column names
        print(series.sort_index())
        

        【讨论】:

        • 我没有为我的计时添加解决方案,因为如果每列重复3 值,则无法正常工作。
        猜你喜欢
        • 1970-01-01
        • 2019-04-18
        • 2021-05-02
        • 2019-05-16
        • 1970-01-01
        • 2019-04-23
        • 2019-02-19
        • 1970-01-01
        • 2023-03-10
        相关资源
        最近更新 更多