AMM*_*AMM 166 python updates dataframe pandas
我有一个像这样的熊猫数据框(它是一个非常大的)
date exer exp ifor mat
1092 2014-03-17 American M 528.205 2014-04-19
1093 2014-03-17 American M 528.205 2014-04-19
1094 2014-03-17 American M 528.205 2014-04-19
1095 2014-03-17 American M 528.205 2014-04-19
1096 2014-03-17 American M 528.205 2014-05-17
Run Code Online (Sandbox Code Playgroud)
现在我想逐行迭代,当我遍历每一行时,每行的值ifor
可以根据某些条件改变,我需要查找另一个数据帧.
现在,我如何在迭代时更新它.尝试了一些他们都没有工作的事情.
for i, row in df.iterrows():
if <something>:
row['ifor'] = x
else:
row['ifor'] = y
df.ix[i]['ifor'] = x
Run Code Online (Sandbox Code Playgroud)
这些方法似乎都不起作用.我没有看到数据框中的值已更新.
rak*_*kke 175
您可以使用df.set_value在循环中指定值:
for i, row in df.iterrows():
ifor_val = something
if <condition>:
ifor_val = something_else
df.set_value(i,'ifor',ifor_val)
Run Code Online (Sandbox Code Playgroud)
如果你不需要行值,你可以简单地迭代df的索引,但是我保留了原始的for循环,以防你需要这里没有显示的东西的行值.
更新
df.set_value()自版本0.21.0以来已被弃用,您可以使用df.at()代替:
for i, row in df.iterrows():
ifor_val = something
if <condition>:
ifor_val = something_else
df.at[i,'ifor'] = ifor_val
Run Code Online (Sandbox Code Playgroud)
piR*_*red 57
Pandas DataFrame对象应该被认为是一系列的系列.换句话说,您应该根据列来考虑它.这很重要的原因是因为当你使用时,pd.DataFrame.iterrows
你正在迭代行作为系列.但这些不是数据框存储的系列,因此它们是在您迭代时为您创建的新系列.这意味着当您尝试分配它们时,这些编辑不会最终反映在原始数据框中.
好的,现在已经不在了:我们该怎么办?
此帖之前的建议包括:
pd.DataFrame.set_value
被弃用的熊猫版0.21pd.DataFrame.ix
已弃用pd.DataFrame.loc
很好,但可以在数组索引器上工作,你可以做得更好我的推荐
使用pd.DataFrame.at
for i in df.index:
if <something>:
df.at[i, 'ifor'] = x
else:
df.at[i, 'ifor'] = y
Run Code Online (Sandbox Code Playgroud)
您甚至可以将其更改为:
for i in df.index:
df.at[i, 'ifor'] = x if <something> else y
Run Code Online (Sandbox Code Playgroud)
如果我需要将前一行的值用于if条件怎么办?
for i in range(1, len(df) + 1):
j = df.columns.get_loc('ifor')
if <something>:
df.iat[i - 1, j] = x
else:
df.iat[i - 1, j] = y
Run Code Online (Sandbox Code Playgroud)
Goi*_*Way 24
您可以使用的方法是itertuples()
,它将DataFrame行作为namedtuples迭代,索引值作为元组的第一个元素.与之相比它要快得多iterrows()
.对于itertuples()
,每个都row
包含Index
在DataFrame中,您可以使用它loc
来设置值.
for row in df.itertuples():
if <something>:
df.at[row.Index, 'ifor'] = x
else:
df.at[row.Index, 'ifor'] = x
df.loc[row.Index, 'ifor'] = x
Run Code Online (Sandbox Code Playgroud)
谢谢@SantiStSupery,使用.at
速度更快.
CT *_*Zhu 17
您应该通过df.ix[i, 'exp']=X
或df.loc[i, 'exp']=X
代替分配值df.ix[i]['ifor'] = x
.
否则你正在研究一个视图,应该变暖:
-c:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_index,col_indexer] = value instead
但当然,循环可能应该更好地被一些矢量化算法取代,以充分利用DataFrame
@Phillip Cloud建议.
小智 16
最好使用以下lambda
功能使用df.apply()
-
df["ifor"] = df.apply(lambda x: {value} if {condition} else x["ifor"], axis=1)
Run Code Online (Sandbox Code Playgroud)
好吧,如果你打算无论如何迭代,为什么不使用最简单的方法, df['Column'].values[i]
df['Column'] = ''
for i in range(len(df)):
df['Column'].values[i] = something/update/new_value
Run Code Online (Sandbox Code Playgroud)
或者,如果要将新值与旧值或类似值进行比较,为什么不将其存储在列表中,然后追加到最后.
mylist, df['Column'] = [], ''
for <condition>:
mylist.append(something/update/new_value)
df['Column'] = mylist
Run Code Online (Sandbox Code Playgroud)
for i, row in df.iterrows():
if <something>:
df.at[i, 'ifor'] = x
else:
df.at[i, 'ifor'] = y
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
177490 次 |
最近记录: |