【问题标题】:Loop, iloc and loc in Dataframe?Dataframe中的循环,iloc和loc?
【发布时间】:2019-05-26 04:02:44
【问题描述】:

大家好,我是 python 新手,现在我开始使用一些库,例如 Pandas 和 Numpy。最近老师给我做这个练习,不知道用什么方法。详情如下:

df1 = pd.DataFrame({'col1': [0, 1, 1, 0, 3],
               'col2': [23, 4, 1, 1, 3], 
               'col3': [0, 5, 2, 1, 1],
               'col4': [1, 2, 6, 4, 0],
               'col5': [4, 15, 0, 2, 5],
               'loc': [1, 4, 2, 3, 2]}) 

1) col1 - col5:随机数

2) loc:值的位置。

3) 计算'val',返回每列的值,位置在'loc'中给出。

示例:在第 0 行,loc = 1,val = 23。在第 1 行,loc = 4,val = 15,等等。

结果应该是这样的:

df = pd.DataFrame({'col1': [0, 1, 1, 0, 3],
               'col2': [23, 4, 1, 1, 3], 
               'col3': [0, 5, 2, 1, 1],
               'col4': [1, 2, 6, 4, 0],
               'col5': [4, 15, 0, 2, 5],
               'loc': [1, 4, 2, 3, 2],
                'val': [23, 15, 2, 4, 1]})

我尝试过 iloc 和 loc 之类的东西来计算“val”。但是,当数据框变大时,我不能再使用这种方法了。有没有更快的方法来计算“val”?我需要使用循环来计算'val'吗?

df1 = df['loc']
df.iloc[0,df1[0]]
df.iloc[1,df1[1]]
df.iloc[2,df1[2]]

PS:对不起我的英语不好,但我真的不知道如何用英语解释这个练习,我只是尽力而为:(

【问题讨论】:

    标签: python python-3.x pandas dataframe


    【解决方案1】:

    使用 numpy 索引,尤其是在性能很重要的情况下:

    df1['value'] = df1.values[np.arange(len(df1)), df1['loc']]
    print (df1)
       col1  col2  col3  col4  col5  loc  value
    0     0    23     0     1     4    1     23
    1     1     4     5     2    15    4     15
    2     1     1     2     6     0    2      2
    3     0     1     1     4     2    3      4
    4     3     3     1     0     5    2      1
    

    性能

    #5000 rows
    df1 = pd.concat([df1] * 1000, ignore_index=True)
    In [73]: %timeit df1['value'] = df1.values[np.arange(len(df1)), df1['loc']]
    266 µs ± 8.06 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
    
    In [74]: %%timeit
        ...: result = []
        ...: for index, row in df1['loc'].iteritems():
        ...:      result.append(df1.iat[index, row])
        ...: df1['val'] = result
        ...: 
    64 ms ± 753 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
    
    In [75]: %timeit df1['value'] = df1.apply(lambda x: x.iloc[x['loc']], axis = 1)
    243 ms ± 11.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    

    【讨论】:

    • 非常感谢,我不知道这种情况下我们可以使用numpy。我确实阅读了一些文档,他们说 numpy 比 pandas 更好地处理大型数据集(可能更快)。但我认为我必须编写代码并阅读更多内容才能使用这两个库。
    【解决方案2】:

    您可以为此使用 for 循环,在其中将值递增到“loc”列的长度范围(例如)。使用.iloc,您可以从“loc”列中选择正确的行和值。

    我不会为你泄露完整的解决方案,但大致如下:

    vals = [] # Create an empty list to hold the requested values
    for i in range(len(df['loc'])): # Loop over the rows ('i')
        val = df.iloc[i, df['loc'][i]] # Get the requested value from row 'i'
        vals.append(val) # append value to list 'vals'
    df['value'] = vals # Add list 'vals' as a new column to the DataFrame
    

    编辑完成答案...

    【讨论】:

    • 感谢您的回答先生,我不得不承认我尝试了这种方法,但我不知道如何处理 for 循环的其余部分。第二行我看懂了但是不知道怎么全部申请:)
    • 这很容易。只需将 val 附加到列表中,然后将其作为新列添加到 df。请参阅上面的编辑...
    【解决方案3】:

    使用索引遍历系列,然后使用 pd.iat[row int pos, column int pos] 您将获得准确的值,您可以从值数组中创建新系列。

    result = []
    for index, row in df1['loc'].iteritems():
         result.append(df1.iat[index, row])
    df1['val'] = result
    

    【讨论】:

      猜你喜欢
      • 2018-02-08
      • 1970-01-01
      • 2021-12-06
      • 1970-01-01
      • 2015-10-14
      • 2020-07-09
      相关资源
      最近更新 更多