关于python:使用索引在pandas DataFrame中设置特定单元格的值

Set value for particular cell in pandas DataFrame using index

我创建了一个熊猫数据框架

1
df = DataFrame(index=['A','B','C'], columns=['x','y'])

得到了这个

1
2
3
4
    x    y
A  NaN  NaN
B  NaN  NaN
C  NaN  NaN

然后我想给特定的单元格赋值,例如行"c"和列"x"。我期望得到这样的结果:

1
2
3
4
    x    y
A  NaN  NaN
B  NaN  NaN
C  10  NaN

用这个代码:

1
df.xs('C')['x'] = 10

但是df的内容没有改变。同样,数据帧中只有EDOCX1[1]。

有什么建议吗?


ruktech的回答是,df.set_value('C', 'x', 10)走的速度,远比我建议下面的选项。然而,它已被slated for deprecation。

什么是.iat/.at前锋,和方法。

为什么不工作:df.xs('C')['x']=10

df.xs('C')默认,返回一个新的下列复制数据,从而

1
df.xs('C')['x']=10

这个新的修改下列只读。

df['x']归来df下列A视图等

1
df['x']['C'] = 10

df本身的修改。

警告:这是很难预测,如果在A或A拷贝操作返回的视图。这是一个原因,是分配上的文档"链式索引"。

因此,建议的替代。

1
df.at['C', 'x'] = 10

这是df修改。

1
2
3
4
5
6
7
8
In [18]: %timeit df.set_value('C', 'x', 10)
100000 loops, best of 3: 2.9 μs per loop

In [20]: %timeit df['x']['C'] = 10
100000 loops, best of 3: 6.31 μs per loop

In [81]: %timeit df.at['C', 'x'] = 10
100000 loops, best of 3: 9.2 μs per loop


更新:.set _价值法是要被取消。.iat /特别是好的文档提供replacements,不幸的小熊猫

这样做是最快的方式使用_值集。本方法是更快的方法比.ix~100倍。例如:

df.set_value('C', 'x', 10)


所以,你可以使用一个查找.loc湖泊在使用条件:

1
df.loc[df[<some_column_name>] == <condition>, []] = <value_to_add>

哪里是你想变量对检查和是你想要添加到柱(柱可以新的或已经存在的那一个)。是你想要添加的价值在那一列/行。

本例子是一个不精确的问题在手的工作,但它可能是有用的为人,想添加一个特定的值基于一种状态。


单(根据演练和维护)集A的值是:

1
df.ix['x','C']=10

使用链式索引(df['x']['C'])可能导致问题。

湖:

  • stackoverflow.com http:/ / / / / 21287235 1579844
  • http://pandas.pydata.org /熊猫/ dev / indexing.html #文档的索引视图和拷贝
  • http:/ / / /熊猫/拉github.com pydata 6031号


尝试使用df.loc[row_index,col_indexer] = value


这是唯一的东西为我工作!

1
df.loc['C', 'x'] = 10

了解更多关于.loc这里。


在我的例子,我选择改变它在细胞

1
2
3
    for index, row in result.iterrows():
        if np.isnan(row['weight']):
            result.at[index, 'weight'] = 0.0

结果是一个"量"列的DataField


你可以使用.iloc

1
df.iloc[[2], [0]] = 10


set_value()是过时的。

从释放的0.23.4"熊猫","未来"……

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> df
                   Cars  Prices (U$)
0               Audi TT        120.0
1 Lamborghini Aventador        245.0
2      Chevrolet Malibu        190.0
>>> df.set_value(2, 'Prices (U$)', 240.0)
__main__:1: FutureWarning: set_value is deprecated and will be removed in a future release.
Please use .at[] or .iat[] accessors instead

                   Cars  Prices (U$)
0               Audi TT        120.0
1 Lamborghini Aventador        245.0
2      Chevrolet Malibu        240.0

这是建议,这是一个演示如何使用他们:

  • 行/列的整数位置。
1
2
3
4
5
6
>>> df.iat[1, 1] = 260.0
>>> df
                   Cars  Prices (U$)
0               Audi TT        120.0
1 Lamborghini Aventador        260.0
2      Chevrolet Malibu        240.0
  • 的行/列的标签
1
2
3
4
5
6
>>> df.at[2,"Cars"] ="Chevrolet Corvette"
>>> df
                  Cars  Prices (U$)
0               Audi TT        120.0
1 Lamborghini Aventador        260.0
2    Chevrolet Corvette        240.0

参考文献:

  • pandas.dataframe.iat
  • pandas.dataframe.at

df.loc['c','x']=10本想和CTH变化值。xth柱。


除了上面的答案,这是一个基准比较不同的方式添加到已存在的数据行下列。它的显示是使用AT或设定值是最有效的方式(至少dataframes大型论文试验条件)。

  • 创建新的下列for each row和……
    • ……附加信息(13)
    • ……串联式(13.1)IT
  • 在另一个容器商店的所有新的行,第一,转换到新添加一次和下列…
    • 容器列表的列表(S)= 2.0)
    • 集装箱的词典列表(S = 1.9)
  • 新的全iterate过下列预分配,和所有的列和行填充使用
    • ……在(0.6)
    • ……集值(0.4)_

现有的测试,包括下列的行和列和1000万NumPy是用随机值。这是添加新的行下列100。

湖下面的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Nov 21 16:38:46 2018

@author: gebbissimo
"""


import pandas as pd
import numpy as np
import time

NUM_ROWS = 100000
NUM_COLS = 1000
data = np.random.rand(NUM_ROWS,NUM_COLS)
df = pd.DataFrame(data)

NUM_ROWS_NEW = 100
data_tot = np.random.rand(NUM_ROWS + NUM_ROWS_NEW,NUM_COLS)
df_tot = pd.DataFrame(data_tot)

DATA_NEW = np.random.rand(1,NUM_COLS)


#%% FUNCTIONS

# create and append
def create_and_append(df):
    for i in range(NUM_ROWS_NEW):
        df_new = pd.DataFrame(DATA_NEW)
        df = df.append(df_new)
    return df

# create and concatenate
def create_and_concat(df):
    for i in range(NUM_ROWS_NEW):
        df_new = pd.DataFrame(DATA_NEW)
        df = pd.concat((df, df_new))
    return df


# store as dict and
def store_as_list(df):
    lst = [[] for i in range(NUM_ROWS_NEW)]
    for i in range(NUM_ROWS_NEW):
        for j in range(NUM_COLS):
            lst[i].append(DATA_NEW[0,j])
    df_new = pd.DataFrame(lst)
    df_tot = df.append(df_new)
    return df_tot

# store as dict and
def store_as_dict(df):
    dct = {}
    for j in range(NUM_COLS):
        dct[j] = []
        for i in range(NUM_ROWS_NEW):
            dct[j].append(DATA_NEW[0,j])
    df_new = pd.DataFrame(dct)
    df_tot = df.append(df_new)
    return df_tot




# preallocate and fill using .at
def fill_using_at(df):
    for i in range(NUM_ROWS_NEW):
        for j in range(NUM_COLS):
            #print("i,j={},{}".format(i,j))
            df.at[NUM_ROWS+i,j] = DATA_NEW[0,j]
    return df


# preallocate and fill using .at
def fill_using_set(df):
    for i in range(NUM_ROWS_NEW):
        for j in range(NUM_COLS):
            #print("i,j={},{}".format(i,j))
            df.set_value(NUM_ROWS+i,j,DATA_NEW[0,j])
    return df


#%% TESTS
t0 = time.time()    
create_and_append(df)
t1 = time.time()
print('Needed {} seconds'.format(t1-t0))

t0 = time.time()    
create_and_concat(df)
t1 = time.time()
print('Needed {} seconds'.format(t1-t0))

t0 = time.time()    
store_as_list(df)
t1 = time.time()
print('Needed {} seconds'.format(t1-t0))

t0 = time.time()    
store_as_dict(df)
t1 = time.time()
print('Needed {} seconds'.format(t1-t0))

t0 = time.time()    
fill_using_at(df_tot)
t1 = time.time()
print('Needed {} seconds'.format(t1-t0))

t0 = time.time()    
fill_using_set(df_tot)
t1 = time.time()
print('Needed {} seconds'.format(t1-t0))


以下是所有用户为按整数和字符串索引的数据帧提供的有效解决方案的摘要。

df.iloc、df.loc和df。对于这两种数据帧类型,df.iloc仅适用于行/列整数索引,df.loc和df.at支持使用列名称和/或整数索引设置值。

当指定的索引不存在时,df.loc和df.at都会将新插入的行/列追加到现有的数据帧,但df.iloc会引发"indexerror:位置索引器超出界限"。在Python2.7和3.7中测试的一个工作示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import numpy as np, pandas as pd

df1 = pd.DataFrame(index=np.arange(3), columns=['x','y','z'])
df1['x'] = ['A','B','C']
df1.at[2,'y'] = 400

# rows/columns specified does not exist, appends new rows/columns to existing data frame
df1.at['D','w'] = 9000
df1.loc['E','q'] = 499

# using df[<some_column_name>] == <condition> to retrieve target rows
df1.at[df1['x']=='B', 'y'] = 10000
df1.loc[df1['x']=='B', ['z','w']] = 10000

# using a list of index to setup values
df1.iloc[[1,2,4], 2] = 9999
df1.loc[[0,'D','E'],'w'] = 7500
df1.at[[0,2,"D"],'x'] = 10
df1.at[:, ['y', 'w']] = 8000

df1
>>> df1
     x     y     z     w      q
0   10  8000   NaN  8000    NaN
1    B  8000  9999  8000    NaN
2   10  8000  9999  8000    NaN
D   10  8000   NaN  8000    NaN
E  NaN  8000  9999  8000  499.0

.iat/.at是很好的解决方案。假设你有这个简单的数据框架:

1
2
3
4
   A   B   C
0  1   8   4
1  3   9   6
2  22 33  52

如果我们想修改单元格的值,[0,"A"]u可以使用这些解决方案之一:

  • df.iat[0,0] = 2
  • df.at[0,'A'] = 2
  • 下面是一个完整的例子,如何使用iat来获取和设置单元格的值:

    1
    2
    3
    4
    def prepossessing(df):
      for index in range(0,len(df)):
          df.iat[index,0] = df.iat[index,0] * 2
      return df

    Y_培训时间:

    1
    2
    3
    4
    5
    6
    7
    8
        0
    0   54
    1   15
    2   15
    3   8
    4   31
    5   63
    6   11

    在调用了iat要更改以使每个单元格的值乘以2的前置函数后进行y训练:

    1
    2
    3
    4
    5
    6
    7
    8
         0
    0   108
    1   30
    2   30
    3   16
    4   62
    5   126
    6   22

    所以,你可以从0.21.1 .at版使用方法。有一些差异,相比.locAS与.loc熊猫。在这里,但它具有单值替换


    如果你想更改的值不完整的行,但只有一些列:

    1
    2
    x = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
    x.iloc[1] = dict(A=10, B=-10)

    我认为这是寻找一个主题,我把一iterate通过下列方式和更新它的查找值从第二下列。这里是我的代码。

    1
    2
    3
    4
    5
    6
    src_df = pd.read_sql_query(src_sql,src_connection)
    for index1, row1 in src_df.iterrows():
        for index, row in vertical_df.iterrows():
            src_df.set_value(index=index1,col=u'etl_load_key',value=etl_load_key)
            if (row1[u'src_id'] == row['SRC_ID']) is True:
                src_df.set_value(index=index1,col=u'vertical',value=row['VERTICAL'])