【问题标题】:how to add row in DataFrame iteratively updating it after each for loop in python preferably in pandas如何在DataFrame中添加行在python中的每个for循环之后迭代更新它,最好在pandas中
【发布时间】:2017-06-15 20:06:39
【问题描述】:

这是我的 .csv 文件

Choco_Type,ID,Cocoa,Milk,Sugar,ID,Cocoa,Milk,Sugar 
Dark,Batch_11,80,0,16,Batch_12,78,0,14 
Milk,Batch_72,35,25,25,Batch_73,32,27,22 
Swiss,Batch_52,30,30,20,Batch_53,28,33,18

这是我的代码

for row in reader_in:
    type_chocolate=row[0]
    a= [(type_chocolate,row[1],row[2],row[3],row[4]),(type_chocolate,row[5],row[6],row[7],row[8])]
    df=DataFrame.from_records(a)

这应该是我的输出数据帧

Choco_Type   ID  Cocoa  Milk Sugar  
Dark    Batch_11    80  0   16  
Dark    Batch_12    78  0   14  
Milk    Batch_72    35  25  25  
Milk    Batch_73    32  27  22  
Swiss   Batch_52    30  30  20  
Swiss   Batch_53    28  33  18      

我无法理解如何在每个“for”循环之后使用新行更新 DataFrame'df',这些新行是通过使用“from_records”函数更新的,该函数从 reader_in 获取可迭代列表作为输入

【问题讨论】:

  • 问题,你为什么一次加载一行?为什么不直接使用read_tableread_csv 阅读整个文件?
  • 我阅读了完整的 csv 文件,但我正在修改每一行,并且我想进一步创建一个 DataFrame

标签: python pandas reshape concat


【解决方案1】:

首先使用read_csvcsv 创建DataFrame

然后replace .1 清空字符串,因为列名中没有重复项。

set_index 使用第一列并使用concat 并通过iloc 选择第一列和最后一个4 列:

import pandas as pd
from pandas.compat import StringIO

temp=u"""Choco_Type,ID,Cocoa,Milk,Sugar,ID,Cocoa,Milk,Sugar
Dark,Batch_11,80,0,16,Batch_12,78,0,14
Milk,Batch_72,35,25,25,Batch_73,32,27,22
Swiss,Batch_52,30,30,20,Batch_53,28,33,18"""
#after testing replace 'StringIO(temp)' to 'filename.csv'
df = pd.read_csv(StringIO(temp))
print (df)

  Choco_Type        ID  Cocoa  Milk  Sugar      ID.1  Cocoa.1  Milk.1  Sugar.1
0       Dark  Batch_11     80     0     16  Batch_12       78       0       14
1       Milk  Batch_72     35    25     25  Batch_73       32      27       22
2      Swiss  Batch_52     30    30     20  Batch_53       28      33       18


df.columns = df.columns.str.replace('.1', '')
df = df.set_index('Choco_Type')
df = pd.concat([df.iloc[:, :4], df.iloc[:, 4:]]).reset_index()

print (df)
  Choco_Type        ID  Cocoa  Milk  Sugar
0       Dark  Batch_11     80     0     16
1       Milk  Batch_72     35    25     25
2      Swiss  Batch_52     30    30     20
3       Dark  Batch_12     78     0     14
4       Milk  Batch_73     32    27     22
5      Swiss  Batch_53     28    33     18

如果需要通过所需的输出更改顺序:

df.columns = df.columns.str.replace('.1', '')
df = df.set_index('Choco_Type')
df = pd.concat([df.iloc[:, :4], df.iloc[:, 4:]], keys=(1,2), axis=1)
       .stack(0)
       .reset_index(level=1, drop=True)
       .reset_index()
print (df)

  Choco_Type        ID  Cocoa  Milk  Sugar
0       Dark  Batch_11     80     0     16
1       Dark  Batch_12     78     0     14
2       Milk  Batch_72     35    25     25
3       Milk  Batch_73     32    27     22
4      Swiss  Batch_52     30    30     20
5      Swiss  Batch_53     28    33     18

另一个解决方案pd.lreshapedictdict comprehension 创建,列名不包含.1,也需要删除Choco_Type

cols = df.columns[~((df.columns.str.contains('.1')) | (df.columns == 'Choco_Type'))]
print (cols)
Index(['ID', 'Cocoa', 'Milk', 'Sugar'], dtype='object')

d = {x: df.columns[df.columns.str.contains(x)].tolist() for x in cols}
print (d)
{'Milk': ['Milk', 'Milk.1'], 
'Sugar': ['Sugar', 'Sugar.1'], 
'ID': ['ID', 'ID.1'], 
'Cocoa': ['Cocoa', 'Cocoa.1']}

df = pd.lreshape(df, d)
print (df)
  Choco_Type  Milk  Sugar        ID  Cocoa
0       Dark     0     16  Batch_11     80
1       Milk    25     25  Batch_72     35
2      Swiss    30     20  Batch_52     30
3       Dark     0     14  Batch_12     78
4       Milk    27     22  Batch_73     32
5      Swiss    33     18  Batch_53     28

【讨论】:

  • str.replace 中的 .1 是什么意思
  • 这意味着列名是ID.1,所以你需要删除.1(这个问题在pandas 0.19.2中,在一些旧版本中,如果列名重复,pandas不会添加.1)跨度>
  • 非常感谢!!!但是你能介意解释一下什么是 reset_index 以及它是如何在这里使用的吗
  • 当然,您可以查看indexing。我从第一列Choco_TypeDataframe 创建索引,其中包含所有用于重塑的数据。 concat 后仍然Choco_Type 是索引,所以我使用reset_index 从索引创建列。
  • 我在使用 filename.csv 时得到了糖的 NAN 值
猜你喜欢
  • 2015-03-19
  • 2019-08-04
  • 2021-02-02
  • 1970-01-01
  • 2021-10-08
  • 1970-01-01
  • 2022-12-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多