【问题标题】:python dataframe indexed by a list由列表索引的python数据框
【发布时间】:2015-06-07 12:18:20
【问题描述】:

我正在尝试获取包含来自有限集合的重复值的 DataFrame 列,并用索引号替换这些值,因此如果值为 [200,20,1000,1],则它们出现的索引将为 [1 ,2,3,4]。 实际数据示例为:

0    aaa
1    aaa
2    bbb
3    aaa
4    bbb
5    bbb
6    ccc
7    ddd
8    ccc
9    ddd

想要的输出是

0    1
1    1
2    2
3    1
4    2
5    2
6    4
7    3
8    4
9    3

我想更改对数字毫无意义的值。就是这样......我不关心索引的顺序,即1可以是3等等,只要顺序是一致的。即,我不在乎 ['aaa','bbb','ccc','ddd'] 是否会被 [1,2,3,4][2,4,3,1] 索引。

假设 DF 名称是 tbl,我只想更改列“aaa”中的索引子集。让我们用 tbl_ind 来表示这些索引。我想要这样做的方式是:

tmp_r = tbl[tbl_ind]
un_r_ind = np.unique(tmp_r)
for r_ind in range(len(un_r_ind)):
    r_ind_ind = np.array(np.where(tmp_r == un_r_ind[r_ind])[0])
    for j_ind in range(len(r_ind_ind)):
        tbl['aaa'].iloc[tbl_ind[r_ind_ind[j_ind]]] = r_ind

它有效。而且在大型数据集上真的很慢。 Python 不允许更新tbl['aaa'].iloc[tbl_ind[r_ind_ind]],因为它是一个索引列表...... 请帮忙?怎么可能加快这个速度? 非常感谢!

【问题讨论】:

  • 您能否发布实际输入数据和所需输出,您的问题没有意义
  • 您是否在问如何查找 df 中存在的一系列值以及如何全部更新它们?例如如果您的值列表是 [200,20, 1000,1] 您想要查找具有这些值的所有行,您想要将所有这些行更改为相同值还是列表中每个条目的不同值?跨度>
  • @EdChum 我添加了一个示例。谢谢。

标签: python list indexing pandas dataframe


【解决方案1】:

您可以将rankdense 方法一起使用:

>>> df[0].rank("dense")
0    1
1    1
2    2
3    1
4    2
5    2
6    3
7    4
8    3
9    4
Name: 0, dtype: float64

这基本上是对值进行排序并将最低值映射到 1,将次低值映射到 2,依此类推。

【讨论】:

    【解决方案2】:

    我不确定我是否从您的示例中理解正确。 这是你想要达到的目标吗? (除了索引上的偏差(零而不是一)):

    df=['aaa','aaa','bbb','aaa','bbb','bbb','ccc','ddd','ccc','ddd']
    idx={}
    
    def index_data(v):
        global idx
    
        if v in idx:
            return idx[v]
        else:
            n = len(idx)
            idx[v] = n
            return n
    
    if __name__ == "__main__":
        outlist = []
        for i in df:
            outlist.append(index_data(i))
        for i, v in enumerate(outlist):
            print i, v
    

    它输出:

    0 0
    1 0
    2 1
    3 0
    4 1
    5 1
    6 2
    7 3
    8 2
    9 3
    

    显然它可以被优化(例如,简单地为 n 增加一个计数器而不是检查索引的大小)

    【讨论】:

    • 谢谢@Pynchia 我试图直接在 tbl['aaa'].iloc[tbl_ind[r_ind_ind]] 上工作,但它没有工作,因为 r_ind_ind 由 r_ind_ind = np.array(np.其中(tmp_r == un_r_ind[r_ind])[0]) 作为合法索引,但 tbl_ind 是一个列表。在应用 tbl_ind[r_ind_ind ] 之前将 tbl_ind 转换为 np.array(tbl_ind) 解决了这个问题。也感谢您的解决方案。
    【解决方案3】:

    我会构造一个您要替换的值的字典,然后调用map

    In [7]:
    
    df
    Out[7]:
      data
    0     
    1  aaa
    2  bbb
    3  aaa
    4  bbb
    5  bbb
    6  ccc
    7  ddd
    8  ccc
    9  ddd
    In [8]:
    
    d = {'aaa':1,'bbb':2,'ccc':3,'ddd':4}
    df['data'] = df['data'].map(d)
    df
    
    Out[8]:
       data
    0      
    1     1
    2     2
    3     1
    4     2
    5     2
    6     3
    7     4
    8     3
    9     4
    

    【讨论】:

    • 如果在数百万个数据点(len[df] = 'very big')中有 50 万个这样的不同值,你会怎么做?我想知道字典的大小以及它的创建方式。有没有一种方法可以快速创建字典,而无需在应用映射之前实际应用 d['fff'] = index 键的所有可能值?谢谢。
    • 您可以只构造一系列不同的值并使用它:所以 df['data'].unique() 返回一系列所有唯一值索引将是自动生成的 int64 索引,因此您可以从 d = dict(zip(df['data'].unique().values, df[data'].unique().index)) 创建一个字典,您可以将最后一个参数替换为 np.arange(len(df['data'].unique()))
    猜你喜欢
    • 2019-02-04
    • 2017-07-24
    • 1970-01-01
    • 2022-06-29
    • 2021-05-27
    • 1970-01-01
    • 2021-03-08
    • 2019-04-08
    • 2017-01-17
    相关资源
    最近更新 更多