按列分组数据框并保存到不同的目录

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

【问题讨论】:

在您的实际文件中,SA 的唯一组跨越多行 - 就像 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(...

以上是关于按列分组数据框并保存到不同的目录的主要内容,如果未能解决你的问题,请参考以下文章

PyQt5 小工具:Excel数据分组汇总器...

如何对每个表进行分组计数并按列打印? [复制]

在 Python 中按列分组以获得总计数

分组数据框并获得总和和计数?

分组数据框并获得总和和计数?

SUM 值按列分组,但不能“聚合”?