获取dataframe的所有单元格作为(索引,列)的元组以传递给df.apply()

时间:2016-01-30 22:42:00

标签: python pandas dataframe indexing

我想获得Pandas数据框中每个单元格的索引和列名。

例如,在从下面的代码生成的数据框中

df = pd.DataFrame({1 : np.arange(1, 6), 
               2 : np.arange(6, 11),
               3 : np.arange(11, 16),
               4 : np.arange(16, 21),
               5 : np.arange(21, 26)}, 
              index=[1, 2, 3, 4, 5])

我想访问值的行索引和值列名的索引/列名组合,例如[1,1]表示1,[2,1]表示2,[3,1]表示3等...

最终目标是使用df.apply()根据数据框中数据框中的位置更新数据框中的每个值。需要从另一个数据帧中提取索引和列名称(n x n数据帧中的等效和有序标识符)。

谢谢!

2 个答案:

答案 0 :(得分:2)

我建议使用自己的功能来做到这一点。您可以使用类似dict的表示法访问数据框的每一列。除了通过访问所需的索引/行来获取所需的元素之外,我将使用.ix,如下所示

import pandas as pd

df = pd.DataFrame({1 : np.arange(1, 6), 
               2 : np.arange(6, 11),
               3 : np.arange(11, 16),
               4 : np.arange(16, 21),
               5 : np.arange(21, 26)}, 
              index=[1, 2, 3, 4, 5])

def get_from_coords(df, x, y):
    return df[x].ix[y]

例如:

In [2]: get_from_coords(df, 2, 1)
Out[2]: 6

文档提供了有关indexing pandas dataframes的详细信息。

更新,因为我错过了在评论中澄清的问题:

def look_for_value(df, value):
    l = []
    for row in df.itertuples():
        print(row)
        if value in row[1:]:
            # appending a tuple of the format `(index name, column name)`
            l.append((row[0], df.columns[row.index(value)-1]))
    return l


def look_using_generator(df, value):
    return [(row[0], df.columns[row.index(value)-1]) for row in df.itertuples() if value in row[1:]]

我正在使用.itertuples()迭代数据框的所有行,这比.iterrows()更快并且正在查找所需的条目/值。如果在行中找到该值,则包含索引和列名称的元组将存储到最后返回的列表中。我在第一个函数中提供了一种逐步的解决方案,并在列表理解中使用了一个生成器。

编辑,因为OP指出他需要使用列名和索引名来更改相应的值:

假设我们要查找所有值6并将其替换为66

for item in look_using_generator(df, 6):
    df[item[0]].ix[item[1]] = 66

答案 1 :(得分:0)

使用df.columns[column position]获取列标签。反过来:使用df.columns.get_loc("column label")获取列位置。

类似于行,df.index[row position]来获取行索引。反过来:使用df.index.get_loc('index label')获取行位置。

至于你的问题,可以直接按行和列位置循环数据框,然后通过.iloc访问

E.g:

def lookup(df, value):
    l = []
    for i in range(df.shape[0]):
        for j in range(df.shape[1]):
            if df.iloc[i, j] == value:
                l.append((df.index[i], df.columns[j]))
    return l