我是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:抱歉英语不好!!
答案 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对象的一种方法,但是您在列表中调用它,而不是数据帧本身。