首页 文章

如何迭代Pandas中的DataFrame中的行?

提问于
浏览
933

我有一只来自熊猫的 DataFrame

import pandas as pd
inp = [{'c1':10, 'c2':100}, {'c1':11,'c2':110}, {'c1':12,'c2':120}]
df = pd.DataFrame(inp)
print df

输出:

c1   c2
0  10  100
1  11  110
2  12  120

现在我想迭代这个帧的行 . 对于每一行,我希望能够通过列的名称访问其元素(单元格中的值) . 例如:

for row in df.rows:
   print row['c1'], row['c2']

是不是可以在熊猫中做到这一点?

我找到了similar question . 但它没有给我我需要的答案 . 例如,建议使用:

for date, row in df.T.iteritems():

要么

for row in df.iterrows():

但我不明白 row 对象是什么以及如何使用它 .

14 回答

  • 16

    恕我直言,最简单的决定

    for ind in df.index:
         print df['c1'][ind], df['c2'][ind]
    
  • 189

    虽然 iterrows() 是一个不错的选择,但有时 itertuples() 可以更快:

    df = pd.DataFrame({'a': randn(1000), 'b': randn(1000),'N': randint(100, 1000, (1000)), 'x': 'x'})
    
    %timeit [row.a * 2 for idx, row in df.iterrows()]
    # => 10 loops, best of 3: 50.3 ms per loop
    
    %timeit [row[1] * 2 for row in df.itertuples()]
    # => 1000 loops, best of 3: 541 µs per loop
    
  • 1

    我在找 How to iterate on rows AND columns and ended here so :

    for i, row in df.iterrows():
        for j, column in row.iteritems():
            print(column)
    
  • 128

    要在pandas中迭代DataFrame的行,可以使用:

    for index, row in df.iterrows():
        print row["c1"], row["c2"]
    
    for row in df.itertuples(index=True, name='Pandas'):
        print getattr(row, "c1"), getattr(row, "c2")
    

    itertuples() 应该比 iterrows() 更快

    但请注意,根据文档(目前的pandas 0.21.1):

    • iterrows: dtype 可能在行与行之间不匹配

    因为iterrows为每一行返回一个Series,所以它不会在行中保留dtypes(dtypes在DataFrames的列之间保留) .

    • iterrows:不要修改行

    你永远不应该修改你正在迭代的东西 . 这并不能保证在所有情况下都有效 . 根据数据类型,迭代器返回副本而不是视图,并且写入它将不起作用 .

    改为使用DataFrame.apply()

    new_df = df.apply(lambda x: x * 2)
    
    • itertuples:

    如果列名称是无效的Python标识符,重复或以下划线开头,则列名称将重命名为位置名称 . 使用大量列(> 255)时,将返回常规元组 .

  • 1352

    使用itertuples() . 它比iterrows()更快:

    for row in df.itertuples():
        print "c1 :",row.c1,"c2 :",row.c2
    
  • 70

    你可以编写自己的迭代器来实现 namedtuple

    from collections import namedtuple
    
    def myiter(d, cols=None):
        if cols is None:
            v = d.values.tolist()
            cols = d.columns.values.tolist()
        else:
            j = [d.columns.get_loc(c) for c in cols]
            v = d.values[:, j].tolist()
    
        n = namedtuple('MyTuple', cols)
    
        for line in iter(v):
            yield n(*line)
    

    这与 pd.DataFrame.itertuples 直接相当 . 我的目标是以更高的效率执行相同的任务 .


    对于具有我的函数的给定数据帧:

    list(myiter(df))
    
    [MyTuple(c1=10, c2=100), MyTuple(c1=11, c2=110), MyTuple(c1=12, c2=120)]
    

    或者使用 pd.DataFrame.itertuples

    list(df.itertuples(index=False))
    
    [Pandas(c1=10, c2=100), Pandas(c1=11, c2=110), Pandas(c1=12, c2=120)]
    

    A comprehensive test
    我们测试使所有列可用并对列进行子集化 .

    def iterfullA(d):
        return list(myiter(d))
    
    def iterfullB(d):
        return list(d.itertuples(index=False))
    
    def itersubA(d):
        return list(myiter(d, ['col3', 'col4', 'col5', 'col6', 'col7']))
    
    def itersubB(d):
        return list(d[['col3', 'col4', 'col5', 'col6', 'col7']].itertuples(index=False))
    
    res = pd.DataFrame(
        index=[10, 30, 100, 300, 1000, 3000, 10000, 30000],
        columns='iterfullA iterfullB itersubA itersubB'.split(),
        dtype=float
    )
    
    for i in res.index:
        d = pd.DataFrame(np.random.randint(10, size=(i, 10))).add_prefix('col')
        for j in res.columns:
            stmt = '{}(d)'.format(j)
            setp = 'from __main__ import d, {}'.format(j)
            res.at[i, j] = timeit(stmt, setp, number=100)
    
    res.groupby(res.columns.str[4:-1], axis=1).plot(loglog=True);
    
  • 13

    iterrows是一个生成索引和行的生成器

    for index, row in df.iterrows():
       print row['c1'], row['c2']
    
    Output: 
       10 100
       11 110
       12 120
    
  • 5

    您还可以进行 numpy 索引以获得更高的速度 . 对于某些应用程序来说,它并不是真正的迭代,而是比迭代更好 .

    subset = row['c1'][0:5]
    all = row['c1'][:]
    

    您可能还想将其强制转换为数组 . 这些索引/选择应该像Numpy数组一样,但我遇到了问题,需要进行转换

    np.asarray(all)
    imgs[:] = cv2.resize(imgs[:], (224,224) ) #resize every image in an hdf5 file
    
  • 20

    您还可以使用 df.apply() 迭代行并访问函数的多个列 .

    docs: DataFrame.apply()

    def valuation_formula(x, y):
        return x * y * 0.5
    
    df['price'] = df.apply(lambda row: valuation_formula(row['x'], row['y']), axis=1)
    
  • 3

    除了上面的答案,有时一个有用的模式是:

    # Borrowing @KutalmisB df example
    df = pd.DataFrame({'col1': [1, 2], 'col2': [0.1, 0.2]}, index=['a', 'b'])
    # The to_dict call results in a list of dicts
    # where each row_dict is a dictionary with k:v pairs of columns:value for that row
    for row_dict in df.to_dict(orient='records'):
        print(row_dict)
    

    结果如下:

    {'col1':1.0, 'col2':0.1}
    {'col1':2.0, 'col2':0.2}
    
  • 8

    要循环 dataframe 中的所有行,您可以使用:

    for x in range(len(date_example.index)):
        print date_example['Date'].iloc[x]
    
  • 57

    为什么复杂的事情?

    简单 .

    import pandas as pd
    import numpy as np
    
    # Here is an example dataframe
    df_existing = pd.DataFrame(np.random.randint(0,100,size=(100, 4)), columns=list('ABCD'))
    
    for idx,row in df_existing.iterrows():
        print row['A'],row['B'],row['C'],row['D']
    
  • 4

    您可以使用df.iloc函数,如下所示:

    for i in range(0, len(df)):
        print df.iloc[i]['c1'], df.iloc[i]['c2']
    
  • 12

    要循环 convenientlydataframeuse 值中的所有行, namedtuples 可以转换为 ndarray s . 例如:

    df = pd.DataFrame({'col1': [1, 2], 'col2': [0.1, 0.2]}, index=['a', 'b'])
    

    迭代行:

    for row in df.itertuples(index=False, name='Pandas'):
        print np.asarray(row)
    

    结果是:

    [ 1.   0.1]
    [ 2.   0.2]
    

    请注意,如果 index=Truethe index is added as the first element of the tuple ,这可能是某些应用程序所不希望的 .

相关问题