我正在寻找一种有效的方法来重复更新DataFrame中的行。我的意思是更改行值及其索引标签。我特别需要帮助后者。我能找到的最好的是How to change Pandas dataframe index value?但是,这会更新整个索引,而我关心的是单个索引标签。
不支持直接分配到index [n]:
>>> df.index[1] = 'new_label'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/pandas/indexes/base.py", line 1374, in __setitem__
raise TypeError("Index does not support mutable operations")
是否可以修改(赋值)索引下的numpy数组?
>>> df.index._values[1] = 'new_label'
更新不会破坏索引排序。
更多背景信息:
我有一个由timestamps(DatetimeIndex)索引的DataFrame,我需要实时有效地追加新行(每秒多次)。我使用NaT / NaN预先分配一个大的固定大小的DataFrame,然后通过写入下一个空行来追加行。
答案 0 :(得分:1)
每秒多次更新dataframe
效率不高。您应该附加一个列表,然后将列表转换为数据帧。
这样有:
log=list()
for i in range(1,10): # here is your loop every minutes where log is updated
log.append([date, value1, value2])
df = pd.DataFrame(log) # now you create the dataframe after being done updating the list.
答案 1 :(得分:1)
作为Steven G pointed,此更新效率非常低。
最好是创建DataFrames
列表,然后使用concat
:
df1 = pd.DataFrame({'a': [1,2,3]}, index=pd.date_range('2015-01-01', periods=3))
print (df1)
a
2015-01-01 1
2015-01-02 2
2015-01-03 3
df2 = pd.DataFrame({'a': [7,8,9]}, index=pd.date_range('2016-01-01', periods=3))
print (df2)
a
2016-01-01 7
2016-01-02 8
2016-01-03 9
dfs = [df1,df2]
df = pd.concat(dfs)
print (df)
a
2015-01-01 1
2015-01-02 2
2015-01-03 3
2016-01-01 7
2016-01-02 8
2016-01-03 9
然后您可以concat
另一个DataFrame
:
df3 = pd.DataFrame({'a': [3,2,5]}, index=pd.date_range('2017-01-01', periods=3))
print (df3)
a
2017-01-01 3
2017-01-02 2
2017-01-03 5
df = pd.concat([df, df3])
print (df)
a
2015-01-01 1
2015-01-02 2
2015-01-03 3
2016-01-01 7
2016-01-02 8
2016-01-03 9
2017-01-01 3
2017-01-02 2
2017-01-03 5
或使用DataFrame.append
:
df4 = pd.DataFrame({'a': [3,2,4]}, index=pd.date_range('2018-01-01', periods=3))
print (df4)
a
2018-01-01 3
2018-01-02 2
2018-01-03 4
df = df.append(df4)
print (df)
a
2015-01-01 1
2015-01-02 2
2015-01-03 3
2016-01-01 7
2016-01-02 8
2016-01-03 9
2017-01-01 3
2017-01-02 2
2017-01-03 5
2018-01-01 3
2018-01-02 2
2018-01-03 4
替换索引中的值的解决方案:
你可以使用与df.index._values[1] = 'new_label'
非常相似的只删除_
而另一个解决方案是Index.set_value
:
df = pd.DataFrame({'a': [1,2,3]}, index=pd.date_range('2016-01-01', periods=3))
print (df)
a
2016-01-01 1
2016-01-02 2
2016-01-03 3
df.index.values[0] = pd.Timestamp(2016,11,23,1,0,0)
df.index.set_value(df.index, df.index[1], pd.Timestamp(2016,11,22,1,0,0))
print (df)
a
2016-11-23 01:00:00 1
2016-11-22 01:00:00 2
2016-01-03 00:00:00 3