按列分组数据框并保存到不同的目录
Posted
技术标签:
【中文标题】按列分组数据框并保存到不同的目录【英文标题】:Groupby dataframe by columns and save to different directories 【发布时间】:2020-12-03 11:25:03 【问题描述】:我有以下数据集:
X Y Z S A
_ _ _ _ _
0 1 2 1 1
8 5 3 1 2
5 6 7 2 1
9 8 9 2 2
6 7 7 1 3
我想像这样将它们的 S 和 A 列相应地文件夹
DATA\S1\A1
DATA\S1\A2
DATA\S2\A1
我只想要我的 csv 文件中对应的 XYZ 值
我已经尝试过这段代码。文件夹的创建工作,但我无法将相应的 csv 文件保存到正确的文件夹中。我应该如何解决这个问题
df 是包含 3 个不同 pandas-dataframes 的列表
def write2path(df):
path = getcwd()
subjects = ["subject%d"%i for i in range(1,31)]
activities = [str(i) for i in range(1,7)]
try:
path = path + "\\DATA"
mkdir(path)
for l in subjects:
temp_path = path +"\\"+ l
mkdir(temp_path)
for k in activities:
temp_path_child = temp_path +"\\" + k
mkdir(temp_path_child)
for j in range(len(df)):
ch='x'
for i, x in df[j].loc[(['Subject0'] == int(l[7])) & (['Activity0'] == int(k))]:
print(x)
val=chr(ord(ch)+j)
x.to_csv(temp_path_child+"\\"+f'sensor-val.csv', index=False)
return self._engine.get_loc(self._maybe_cast_indexer(key))
File "pandas\_libs\index.pyx", line 111, in pandas._libs.index.IndexEngine.get_loc
File "pandas\_libs\index.pyx", line 135, in pandas._libs.index.IndexEngine.get_loc
File "pandas\_libs\index_class_helper.pxi", line 109, in pandas._libs.index.Int64Engine._check_type
KeyError: False
what i am trying to achieve
【问题讨论】:
在您的实际文件中,S
和 A
的唯一组跨越多行 - 就像 DATA\S1\A1
会有不止一行?您当前的 df 将作为单行输出,您还可以解释文件名的逻辑吗?
当然。在我的实际数据集中,我有 7300 行对应于多个“主题”和“活动”(6 个活动标签 30 个主题标签)。我想要一个 DATA 目录作为每个主题目录的父目录。每个主题目录都会有 Activity(1,2,3,4,5,6) 目录。在活动目录中,我将包含包含 X Y Z 主题活动作为列的 csv 文件。 DATA\subject1\Activity1\x-value.csv
我添加了一张我想要为你实现的目标的图片。
【参考方案1】:
让我们使用 pathlib 并使用一些整洁的函数。
from pathlib import Path
def create_folder(path):
if not path.is_dir():
path.mkdir(parents=True)
def if_file_exists(filename,trg_folder,dataframe):
if trg_folder.joinpath(file).is_file():
# if file exists then write behavior here.
else:
dataframe.to_csv(trg_folder.joinpath(filename),index=False)
然后在下面的变量和 groupby 中列出您完全合格的 start_dir - 写入您的目录。
start_dir = r'your_start_dir' # like /tmp/files/data
for paths, group in df.groupby(['S','A']):
paths = list(map(str,paths)) # if ints.
target_folder = Path(start_dir).joinpath('DATA','S'+paths[0],'A'+paths[1])
create_folder(target_folder)
file_name = f"Spaths[0]-Apaths[1].csv"
if_file_exists(file_name,target_folder,group)
df = pd.read_csv("your_start_dir\DATA\S1\A1\S1-A1.csv")
print(df)
X Y Z S A
0 0 1 2 1 1
【讨论】:
感谢您的帮助。 def create_folder(path): 的用途是什么?我们没有使用它 @Nightingale 我的错对不起 - 复制时错过了它,请参阅编辑 - 它用于检查文件夹是否存在,如果不创建它,将其放在函数中的目的是添加如果需要的话,任何额外的功能可以让你的代码更简洁,更容易维护。 @Nightingale 谢谢 - 我会考虑一种更好的方法来生成文件夹名称而不是字符串插值(如果你说 3 个或更多变量,它会很快变得混乱) 谢谢,我找到了解决方案,``` for j in range(len(df)): ch='x' for paths, group in df[j].groupby( ['Subject0','Activity0']): val=chr(ord(ch)+j) file_name = f"sensor-val.csv" ```【参考方案2】:如果您想为“S”和“A”的每个组合创建一个 csv 文件(例如 data.csv),那么您可以执行 groupby,然后遍历每个组,分别保存每个组
样本
df = pd.DataFrame(
'X': [0,8,5,9,6],
'Y': [1,5,6,8,7],
'Z': [2,3,7,8,7],
'S': [1,1,2,2,1],
'A': [1,2,1,2,3]
)
for group_name, df_group in df.groupby(['S','A']):
S = f"Sgroup_name[0]"
A = f"Agroup_name[1]"
p = os.path.join(S, A)
if not os.path.exists(p):
os.makedirs(p)
df_group[['X', 'Y', 'Z']].reset_index(drop=True).to_csv(os.path.join(p, f"S_A.csv"), index=False)
您将在以下目录结构中获得文件:
【讨论】:
非常感谢,我对此有点新意。假设我们在一个文件中有 3 个以上的列,我该如何编辑该部分df_group[['X', 'Y', 'Z']]
只需将您想要的列添加到列表中。假设您还想保存“C”列,那么您将不得不这样做df_group[['X', 'Y', 'Z', 'C']]
我有 128 个
您已经在每次迭代中拥有该组,print(group_name) - 请参阅我的答案。
如果你想要全部,那么只需使用df_group.reset_index(drop=True).to_csv(...
以上是关于按列分组数据框并保存到不同的目录的主要内容,如果未能解决你的问题,请参考以下文章