【问题标题】:Store files in different subdirectories using python使用python将文件存储在不同的子目录中
【发布时间】:2021-09-29 21:46:39
【问题描述】:

我有一个熊猫数据框df,看起来像这样:

import pandas as pd
d = {'user': ['Peter', 'Peter', 'Peter', 'Peter', 'David', 'David', 'David', 'Emma', 'Joyce', 'Joyce', 'Joyce'], 'date': ['2019-03-04', '2019-03-04', '2019-03-04', '2019-03-04', '2019-03-04', '2019-03-04', '2019-03-04', '2019-03-04', '2019-03-04', '2019-03-04', '2019-03-04'], 'lat': [37.749798119650926, 37.751028173710736, 37.751698332490214, 37.75180012822952, 38.122893081890844, 38.124108467926035, 38.12743379574882, 37.89363489791644, 37.53620628385582, 37.53804390907164, 37.54044296272588], 'lon': [-122.49230146408082, -122.49229073524474, -122.49170064926147, -122.48974800109862, -122.24205136299133, -122.23907947540283, -122.23867177963257, -122.07653760910033, -121.99707984924316, -121.99315309524536, -121.9914150238037]}
df = pd.DataFrame(data=d)
df

user    date        lat         lon
Peter   2019-03-04  37.749798   -122.492301
Peter   2019-03-04  37.751028   -122.492291
Peter   2019-03-04  37.751698   -122.491701
Peter   2019-03-04  37.751800   -122.489748
David   2019-03-04  38.122893   -122.242051
David   2019-03-04  38.124108   -122.239079
David   2019-03-04  38.127434   -122.238672
Emma    2019-03-04  37.893635   -122.076538
Joyce   2019-03-04  37.536206   -121.997080
Joyce   2019-03-04  37.538044   -121.993153
Joyce   2019-03-04  37.540443   -121.991415

使用下面的代码,我可以创建四个单独的 folium 地图,按用户分组,在地图上显示坐标。四个地图文件以用户命名:Peter.htmlDavid.htmlEmma.htmlJoyce.html

import folium

users = list(df.user.unique())

def create_user_map(user):
    m = folium.Map(location=[37.733795, -122.446747], 
           zoom_start=9, 
           min_zoom=10, 
           max_zoom=19,
           control_scale=True)
 
    df_user = df[df.user==user]
    for row in df_user.itertuples():
         folium.CircleMarker( location=[row.lat, row.lon],
            radius=4,
            fill=True,
           fill_opacity=0.5).add_to(m)
    return m

for user in users:
    user_map = create_user_map(user)
    user_file = f"{user}.html"
    user_map.save(user_file)

现在我想根据下面的文件夹结构将这些文件自动存储在相应的子目录中。如何扩展上面的循环来实现这一点?

Report/
└── Report_per_date/ 
    ├── 2019-03-01/
    ├── 2019-03-02/
    ├── 2019-03-03/
    └── 2019-03-04/
         └── Users/
             └── Peter/
                 └── Peter.html
             └── David/
                 └── David.html
             └── Emma/
                 └── Emma.html
             └── Joyce/
                 └── Joyce.html

我希望我能做到以下几点:

import os
rootdir = pathlib.Path('./Report')
report_per_date = df.apply(lambda x: rootdir / 'Report_per_date' / x['date'] / 'Users' / x['user'] / f"{x['user']}.html", axis='columns')

for mapfile, data in df.groupby(report_per_date):
    mapfile.parent.mkdir(parents=True, exist_ok=True)
    user_map = create_user_map(user)
    user_map.save(mapfile)

不幸的是,这返回了AttributeError: 'PosixPath' object has no attribute 'write'

【问题讨论】:

    标签: python directory directory-structure folium


    【解决方案1】:

    您可以更改循环以包含日期,还可以在您的 df 中创建一个“路径”列。

    df['path'] = df.apply(lambda x: rootdir / 'Report_per_date' / x['date'] / 'Users' / x['user'] / f"{x['user']}.html",
                          axis='columns')
    
    dates = list(df.date.unique())
    
    
    def create_user_map(df_user):
        m = folium.Map(location=[37.733795, -122.446747], 
                   zoom_start=9, 
                   min_zoom=10, 
                   max_zoom=19,
                   control_scale=True)
     
        for row in df_user.itertuples():
              folium.CircleMarker( location=[row.lat, row.lon],
                    radius=4,
                    fill=True,
                    fill_opacity=0.5).add_to(m )
         
        return m
    
    for user in users:
        for date in dates:
            data = df[(df.user==user)&(df.date==date)]
            path = data.iloc[0]['path']        
            path.parent.mkdir(parents=True, exist_ok=True)            
            user_map = create_user_map(data)
            user_map.save(str(path))
    

    【讨论】:

      【解决方案2】:

      我在我的机器上尝试了代码,遇到了类似的问题,但得到了AttributeError: 'WindowsPath' object has no attribute 'write'

      Folium 似乎使用模块 branca 来保存到 HTML,并且似乎 branca 无法写入路径对象。我可以通过将路径转换为字符串来修复它:

      user_map.save(str(mapfile))
      

      这解决了我的机器上的问题,并且因为你之前使用字符串时 user_map.save() 工作,这可能也对你有用。

      另外,在下面的 sn-p 中,您正在对变量 user 调用 create_user_map。

      for mapfile, data in df.groupby(report_per_date):
          mapfile.parent.mkdir(parents=True, exist_ok=True)
          user_map = create_user_map(user)
          user_map.save(mapfile)
      

      但在此示例中,这将始终是 Joyce,因为这是从上面的 for user in users: 部分遗留下来的。一个想法是从循环中的路径获取用户,如下所示:

      for mapfile, data in df.groupby(report_per_date):
          mapfile.parent.mkdir(parents=True, exist_ok=True)
          user_map = create_user_map(mapfile.stem)
          user_map.save(str(mapfile))
      

      这是可行的,因为 .stem 返回的文件名不带扩展名。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-21
        相关资源
        最近更新 更多