如何在python中使用for的数据框属性?

时间:2018-04-22 05:56:34

标签: python pandas dataframe pandas-groupby

我是python的新手,所以我会尽可能详细。

我试图在其上实施装袋算法(我需要为我的最终论文实现,所以基本上我不能使用已经实现的那个)。

我有一个包含X类的CSV文件。我想要做的是用pandas读取csv,在我读完之后我想为每个类创建一个数据帧读取csv文件,最后创建一个包含所有这些新DataFrame的新CSV文件。我已经针对特定的CSV文件执行了此操作,但我需要将其设为通用。

这是我制作的代码。它适用于一个特定的CSV文件:

import pandas as pd

#Function of percentage
def percentage(number1, number2):
    percent = (number1 * number2) / 100
    return percent

#read the csv file
dataFrame = pd.read_csv('Monk.csv', sep=',')

#select all the values of the dataframe with the column class = 1, do the same for class = 2
class1 = dataFrame[dataFrame['Class'] == 1]
class2 = dataFrame[dataFrame['Class'] == 2]

#reset the index of the new dataframes
class1 = class1.reset_index(drop=True)
class2 = class2.reset_index(drop=True)

#return the quantity of rows
lenClass1 = class1.__len__()
lenClass2 = class2.__len__()

#randomly select n rows of eache class dataframe
randClass1 = class1.sample(n=int(percentage(lenClass1, 33)))
randClass2 = class2.sample(n=int(percentage(lenClass2, 33)))

subSet= randClass1.append(randClass2)
subSet = subSet.sample(frac=1)
subSet = subSet.reset_index(drop=True)
subSet.to_csv('MonkSub1.csv', sep=',')

使用此代码我得到了这个:

数据帧

     A1    A2    Class
01   a     b      1
02   x     a      2
03   f     a      2
04   r     b      1
05   l     a      2
06   s     b      1

之后我将新数据帧中的数据帧分开

的Class1

     A1    A2    Class
01   a     b      1
04   r     b      1
06   s     b      1

第2类

     A1    A2    Class    
02   x     a      2
03   f     a      2
05   l     a      2

然后我重置索引

的Class1

     A1    A2    Class
01   a     b      1
02   r     b      1
03   s     b      1

第2类

     A1    A2    Class    
01   x     a      2
02   f     a      2
03   l     a      2

因此,我根据每个DataFrame中行的百分比随机选择每个新DataFrame的行数,并使用选中的行创建一个新CSV。例如,使用33%我将选择1行Class1和1行Class2选择ramdonly。

NewCSV

     A1    A2    Class    
02   r     b      1
01   x     a      2

最后我重置了这个新DataFrame的索引。

在此之后,我尝试对通用文件执行相同操作。我的想法是阅读带有pandas的CSV文件,之后该组将DataFrames分隔为具有相似值的“Class'”(如上例所示)。在这方面是问题所在。我尝试使用groupby()函数,但使用新DataFrame的type()函数,我得到pandas.core.groupby.DataFrameGroupBy。使用DataFrameGroupBy我无法使用DataFrame的所有属性,那么我使用它:

dataFrame = pd.read_csv('Monk.csv', sep=',')    
grouped = dataFrame.groupby(["Class"])
test= grouped.apply(lambda x:x)

当我使用type()功能打印test时,它会返回:pandas.core.frame.DataFrame。基本上我做了我想做的一切,但在那之后我的问题开始了。我需要在列表或数组上保存所有新的DataFrame,迭代它们并重置索引(reset_index()),根据行总数(sample())获取具有百分比值的样本以及我可以在DataFrame中使用的其他函数,但我不能,因为在for的内部我不能使用所有这些DataFrames属性。

for df in test.iterrows():
    FrameList = [df]
    FrameList.reset_index(drop= True)

但是我得到了错误:AttributeError: 'list' object has no attribute 'reset_index'。 我不知道该怎么做,我已经尝试了很多东西,但没有一个能奏效。

ps:抱歉英语不好!!

2 个答案:

答案 0 :(得分:1)

在我看来,您正在尝试创建一个较大文件的子集,其中子集中的类与较大文件中的类成比例。你需要一个分层的样本。

如果你有一个这样的数据帧,请使用以下类摘要。

df = pd.DataFrame({'class': list('aabbb')*4,
                   'val': np.arange(20)}); df

Out[106]: 
   class  val
0      a    0
1      a    1
2      b    2
3      b    3
4      b    4
5      a    5
6      a    6
7      b    7
8      b    8
9      b    9
10     a   10
11     a   11
12     b   12
13     b   13
14     b   14
15     a   15
16     a   16
17     b   17
18     b   18
19     b   19

df.groupby('class').count()
Out[107]: 
       val
class     
a        8
b       12

如果你想创建一个25%(为了保持数学简单)分层样本,那么你的最终数据框将有5个obs,其中2个来自' a'来自' b'保持比例。这可以很容易地完成。

dfsub = df.groupby('class', as_index=False).apply(lambda x: x.sample(frac=.25)).reset_index(drop=True); dfsub
Out[109]: 
  class  val
0     a    0
1     a    6
2     b   18
3     b   17
4     b    7

从此处您可以将其写入CSV。

答案 1 :(得分:0)

for df in test.iterrows():
    FrameList = [df]
    FrameList.reset_index(drop= True)
  

但是我得到了错误:AttributeError:'list'对象没有属性   'reset_index'。我不知道该怎么办,我已经尝试了很多   事情,但没有一个工作

FrameList = [df]创建一个包含数据框的新列表...

reset_index()是dataframe对象的一种方法,但是您在列表中调用它,而不是数据帧本身。