【问题标题】:Converting a pandas dataframe to a list of entries将 pandas 数据框转换为条目列表
【发布时间】:2018-07-13 17:51:59
【问题描述】:

我有一个来自 numpy 数组的数据框。

matrix = scipy.sparse.rand(5, 3, density=0.2, format='lil')
array = numpy.array(matrix.toarray())
users = {5: 0, 10: 1, 15: 2, 20: 3, 25: 4}
games = {1: 0, 4: 1, 6: 2}
dataframe = pd.DataFrame(data=array, index=users.keys(), columns=games.keys())

我现在需要的是从该数据帧中获取一个列表,其中矩阵中的每个单元格都表示为以下格式的元组:

userID, gameID, value
userID, gameID, value
userID, gameID, value
...

http://surprise.readthedocs.io/en/stable/getting_started.html#load-custom一起使用

有什么有效的方法吗?

【问题讨论】:

  • 是的,但没有您自己的试用代码,很难让您知道您的试用代码是否比其他人更有效....通过发布您的尝试,您可以通过评论或发布的答案获得通知问题得到解答。在您当前的问题信息下方添加您的跟踪代码。

标签: python list pandas dataframe tuples


【解决方案1】:

首先使用stack 进行整形:

...并为 3 个级别添加列 MultiIndex 并将其转换为 tuples

L = dataframe.stack().to_frame('a').set_index('a', append=True).index.tolist()

...或reset_indexlist comprehension

L = [tuple(x) for x in dataframe.stack().reset_index().values]

print (L)

[(5, 1, 0.8797632578062221), (5, 4, 0.0), 
 (5, 6, 0.8996885724198237), (10, 1, 0.0), (10, 4, 0.0), 
 (10, 6, 0.0), (15, 1, 0.0), (15, 4, 0.07758205674008478), 
 (15, 6, 0.0), (20, 1, 0.0), (20, 4, 0.0), (20, 6, 0.0), 
 (25, 1, 0.0), (25, 4, 0.0), (25, 6, 0.0)]

如果只想要非0 值,则只需按query 过滤:

L = [tuple(x) for x in dataframe.stack().reset_index(name='a').query('a != 0').values]
print (L)

[(5.0, 1.0, 0.87976325780622211), 
 (5.0, 6.0, 0.8996885724198237), 
 (15.0, 4.0, 0.077582056740084782)]

【讨论】:

    【解决方案2】:
    l = []
    for row in dataframe.itertuples():
        for col in dataframe.columns:
            l.append((row.Index,col, dataframe.loc[row.Index,col]))
    

    您可以遍历每一行,然后遍历每一列,以将结果元组附加到列表中。在我的测试中,这比上一个答案要快,可能取决于您拥有的行数和列数。

    %%timeit
    l = []
    for row in dataframe.itertuples():
        for col in dataframe.columns:
            l.append((row.Index,col, dataframe.loc[row.Index,col]))
    

    每个循环 594 µs ± 1.5 µs(7 次运行的平均值 ± 标准偏差,每次 1000 个循环)

    L = dataframe.stack().to_frame('a').set_index('a', append=True).index.tolist()
    L = [tuple(x) for x in dataframe.stack().reset_index().values]
    

    每个循环 2.25 ms ± 12.4 µs(平均值 ± 标准偏差,7 次运行,每次 100 个循环)

    根据要求,这里是 1000 行的时间:

    matrix = scipy.sparse.rand(1000, 3, density=0.2, format='lil')
    array = numpy.array(matrix.toarray())
    index = list(range(1000))
    dataframe= pd.DataFrame(data=array, index=index)
    
    
    %%timeit
    
    l = []
    for row in dataframe.itertuples():
        for col in dataframe.columns:
            l.append((row.Index,col, dataframe.loc[row.Index,col]))
    

    每个循环 17 ms ± 38 µs(平均值 ± 标准偏差,7 次运行,每次 100 个循环)

    %%timeit -n 100
        L = dataframe.stack().to_frame('a').set_index('a', append=True).index.tolist()
        L = [tuple(x) for x in dataframe.stack().reset_index().values]
    

    每个循环 5.08 ms ± 16.5 µs(7 次运行的平均值 ± 标准偏差,每次 100 个循环)

    【讨论】:

    • 可以为 1000 行添加计时吗?
    • @jezrael 当然。我将它们添加到我的答案中。不出所料,您的重新索引方法可以更好地扩展。
    猜你喜欢
    • 2017-06-22
    • 2021-03-22
    • 2020-09-02
    • 2021-01-22
    • 2021-02-09
    • 2018-03-25
    • 2023-03-21
    • 2018-05-17
    • 2014-06-12
    相关资源
    最近更新 更多