【问题标题】:Reshape and filter pandas dataframe重塑和过滤熊猫数据框
【发布时间】:2019-05-25 21:05:48
【问题描述】:

我想从下面的数据框 (df1) 中过滤掉所有单元格等于 1 的值,并创建一个新的数据框,其中每一行都有来自相应单元格的行和列(如下面的 df2 所示):

dict1 = [{'12/21/18': 0,'12/22/18': 0,'12/23/18': 1,'12/24/18': 1},
     {'12/21/18': 1,'12/22/18': 1,'12/23/18': 0,'12/24/18': 1},
     {'12/21/18': 0,'12/22/18': 1,'12/23/18': 0,'12/24/18': 0},
     {'12/21/18': 1,'12/22/18': 0,'12/23/18': 1,'12/24/18': 1}]


df1 = pd.DataFrame(dict1, index= ['AAPL','CSCO','GE','MSFT' ])

dict2 = [{'Ticker': 'AAPL','Date': '12/23/18'},
     {'Ticker': 'AAPL','Date': '12/24/18'},
     {'Ticker': 'CSCO','Date': '12/22/18'},
     {'Ticker': 'CSCO','Date': '12/24/18'},
     {'Ticker': 'GE',  'Date': '12/22/18'},
     {'Ticker': 'MSFT','Date': '12/24/18'}]


df2 = pd.DataFrame(dict2)

任何人都可以提出如何做到这一点的方法吗?

【问题讨论】:

  • 你只需要融化和过滤它

标签: python pandas dataframe


【解决方案1】:

这是@slayer 和@Lucas H 给​​出的方法的性能比较。我还添加了第三种方法。

@slayer method 
%%timeit 
1.12 ms ± 61.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

@Lucas H method
%%timeit
5.16 ms ± 735 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

@Third method
%%timeit
4.4 ms ± 232 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)


# Third method
df1 = df1.T
df2 = pd.melt(df1.where(df1==0, df1.index))
df2 = df2[df2.value != 0]
df2.columns = ['Ticker', 'Date']

显然@slayer 的方法胜过一切。

【讨论】:

  • 感谢您的比较,也感谢第三种方法,非常感谢您的帮助。我可能仍然会使用 Lucas 或你的方法,因为速度无关紧要,因为我真的很想熟悉 melt!
  • 不错的比较。有时,高效路线并不是最受追捧的路线。
  • 真的很高兴知道,如果我必须将其应用于更大的数据集,我会将您的方法保留在我的备忘单杀手中以防万一,谢谢你们三个!这很有帮助!!!
  • 谢谢我,这将非常有帮助!
【解决方案2】:

您可以尝试查看数据框的值并获取值大于 0 的索引数组。然后您可以使用索引和列名称列表中的索引来构建新的数据框。

import numpy as np
idx = np.argwhere(df1.values > 0)

# Get a list of the ticker index and column names
ticker_list = df1.index.tolist()
date_list = df1.columns.tolist()
ticker = []
date = []

for value in idx:
    ticker.append(ticker_list[value[0]])
    date.append(date_list[value[1]])

df2 = pd.DataFrame({'Ticker': ticker, 'Date': date})

【讨论】:

    【解决方案3】:

    我认为最简单的方法如下:

    df1.index.name = 'Ticker' # First reset the name so it will match your desired output (default is 'index')
    df2 = df1.reset_index().melt(id_vars='Ticker',var_name='Date') # This unstacks the data
    

    最后为了把它变成你想要的形式,我们删除 0,重置索引,然后排序:

    df2 = df2[df2.value == 1].set_index('Ticker').filter(['Date','Ticker']).sort_index()
    

    【讨论】:

      猜你喜欢
      • 2017-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多