【问题标题】:parse multiple dataframes from list of csv links, using date in link titles to concatenate dataframes从 csv 链接列表中解析多个数据帧,使用链接标题中的日期来连接数据帧
【发布时间】:2021-03-26 18:08:37
【问题描述】:

对不起,标题太长了,我在这个逻辑上有点挣扎

我有通过 NOAA 网站的代码,并从他们的学位日目录和子目录建立链接,以建立到他们所有文本文件的链接(我相信这不是最好的方法,所以我不会被冒犯如果有人告诉我这可能会更好):

from bs4 import BeautifulSoup as bs
import requests
import re

topdir = 'https://ftp.cpc.ncep.noaa.gov/htdocs/products/analysis_monitoring/cdus/degree_days/archives/Heating%20degree%20Days/weekly%20states/'
res = requests.get(topdir)
soup = bs(res.text,'html.parser')

toplinks = []
midlinks = []
csvlinks = []

for link in soup.find_all('a'):
    if re.search(r"^2\d{3}\/$", str(link.get('href'))):
        toplinks.append(link.get('href'))
        
for link in toplinks:
    midlink = topdir+str(link)
    midlinks.append(midlink)

for mlink in midlinks:
    mid = requests.get(mlink)
    msoup = bs(mid.text,'html.parser')
    for link in msoup.find_all('a'):
        if re.search(r"^[a-zA-Z]{3}%\d{4},%\d{6}\.txt$",str(link.get('href'))):
            csvlinks.append(mlink+str(link.get('href')))

链接的格式实际上是这样的:https://ftp.cpc.ncep.noaa.gov/htdocs/products/analysis_monitoring/cdus/degree_days/archives/Heating%20degree%20Days/weekly%20states/2021/Mar%2020,%202021.txt 如您所见,链接的末尾表示月、年,然后表示日和年作为一个数字。

每个文件的 csv 格式如下:

            HEATING DEGREE DAY DATA WEEKLY SUMMARY
     POPULATION-WEIGHTED STATE,REGIONAL,AND NATIONAL AVERAGES
              CLIMATE PREDICTION CENTER-NCEP-NWS-NOAA
  
          LAST DATE OF DATA COLLECTION PERIOD IS MAR 20, 2021
          ACCUMULATIONS ARE FROM JUL  1, 2020 TO MAR 20, 2021
           -999 = NORMAL LESS THAN 100 OR RATIO INCALCULABLE
  
   STATE         WEEK  WEEK WEEK    CUM   CUM   CUM   CUM   CUM
                 TOTAL DEV  DEV     TOTAL DEV   DEV   DEV   DEV
                       FROM FROM          FROM  FROM  FROM  FROM
                       NORM L YR          NORM  L YR  NORM  L YR
                                                      PRCT  PRCT
  
 ALABAMA            39  -37   21    2147  -401   235   -16    12
 ALASKA            356   62   68    8372  -552   313    -6     4
 ARIZONA            83   22    4    1853   -43    70    -2     4
 ARKANSAS           67  -29  -19    3077   -70   282    -2    10
 CALIFORNIA        117   36   -6    1944  -126    52    -6     3
 COLORADO          222   18   34    5473  -427    15    -7     0
 ...               ...   ..   ..    ....   ...   ...    ..     .
 WEST VIRGINIA     135  -20    6    4157  -300   337    -7     9
 WISCONSIN         205  -23   -8    6092  -355   154    -6     3
 WYOMING           232    9   -2    6219  -406  -193    -6    -3
   REGION
 NEW ENGLAND       230   26   51    4903  -490    55    -9     1
 MIDDLE ATLANTIC   199   14   50    4418  -484   147   -10     3
 E N CENTRAL       181  -12    5    5082  -351   252    -6     5
 W N CENTRAL       170  -21  -23    5473  -286    86    -5     2
 SOUTH ATLANTIC     77   -6   30    2226  -272   213   -11    11
 E S CENTRAL        63  -37    2    2908  -266   269    -8    10
 W S CENTRAL        47  -11   21    2015   -89   240    -4    14
 MOUNTAIN          153   11    4    4040  -225     4    -5     0
 PACIFIC           127   33   -8    2406  -129    17    -5     1
 
 UNITED STATES     134    2   16    3518  -282   156    -7     5
              GAS HOME HEATING CUSTOMER WEIGHTED
   REGION
 NEW ENGLAND       224   26   52    4737  -468    72    -9     2
 MIDDLE ATLANTIC   198   14   50    4406  -476   150   -10     4
 E N CENTRAL       182  -11    5    5086  -352   251    -6     5
 W N CENTRAL       171  -21  -22    5483  -280    93    -5     2
 SOUTH ATLANTIC    102   -5   37    2866  -316   240   -10     9
 E S CENTRAL        65  -37    1    2944  -269   270    -8    10
 W S CENTRAL        49  -12   19    2104   -79   248    -4    13
 MOUNTAIN          165   10    7    4396  -260    -4    -6     0
 PACIFIC           123   34   -7    2221  -127    31    -5     1

我要检索的每个内容是列标题和第一个“区域”部分(实际上我只需要 WEEK TOTAL 列:

       REGION
     NEW ENGLAND       230   26   51    4903  -490    55    -9     1
     MIDDLE ATLANTIC   199   14   50    4418  -484   147   -10     3
     E N CENTRAL       181  -12    5    5082  -351   252    -6     5
     W N CENTRAL       170  -21  -23    5473  -286    86    -5     2
     SOUTH ATLANTIC     77   -6   30    2226  -272   213   -11    11
     E S CENTRAL        63  -37    2    2908  -266   269    -8    10
     W S CENTRAL        47  -11   21    2015   -89   240    -4    14
     MOUNTAIN          153   11    4    4040  -225     4    -5     0
     PACIFIC           127   33   -8    2406  -129    17    -5     1

我认为最有意义的是让文本文件的日期成为行标识符,将区域作为列标题,并以这种方式不断附加数据框,以便可以按日期对其进行排序。

我正在努力:

  1. 这样做的逻辑和
  2. pd.read_csv 和确定编码

【问题讨论】:

  • 这是一个不错的数据文件,但它不是 csv 文件。我什至不会尝试在这里使用 read_csv,而是直接使用自定义解析器
  • @SergeBallesta 感谢您的意见!我对这些不是很有经验,那会是什么样的?

标签: python pandas dataframe csv


【解决方案1】:

您很幸运,您要提取的表位于所有txt 文件中的相同行号上。这意味着您可以将pd.read_csvskiprows=80nrows=9 一起使用来准确提取此表。此外,使用正则表达式 sep=r"[ ]{2,}" 将多个空格标识为分隔符会将表格放入数据框:

url = "https://ftp.cpc.ncep.noaa.gov/htdocs/products/analysis_monitoring/cdus/degree_days/archives/Heating%20degree%20Days/weekly%20states/2021/Mar%2020,%202021.txt"
df = pd.read_csv(url, names=['REGION', 'GAS', 'HOME', 'HEATING', 'CUSTOMER', 'WEIGHTED', 'CUM DEV FROM L YR', 'CUM DEV FROM NORM PRCT', 'CUM DEV FROM L YR PRCT'], skiprows=80, nrows=9, sep=r"[ ]{2,}", engine='python')

输出:

REGION GAS HOME HEATING CUSTOMER WEIGHTED CUM DEV FROM L YR CUM DEV FROM NORM PRCT CUM DEV FROM L YR PRCT
0 NEW ENGLAND 322 48 100 3095 51 508 2 20
1 MIDDLE ATLANTIC 316 53 110 2864 13 570 0 25
2 E N CENTRAL 335 38 94 3153 -71 520 -2 20
3 W N CENTRAL 335 20 79 3285 -175 517 -5 19
4 SOUTH ATLANTIC 237 56 83 1914 68 301 4 19
5 E S CENTRAL 251 64 88 1950 66 278 4 17
6 W S CENTRAL 174 34 62 1315 18 153 1 13
7 MOUNTAIN 195 -41 -43 2750 -245 130 -8 5
8 PACIFIC 93 -25 -32 1182 -206 -29 -15 -2

您现在可以创建一个 for 循环来处理文件:

for url in csvlinks:
    df = pd.read_csv(url, names=['REGION', 'GAS', 'HOME', 'HEATING', 'CUSTOMER', 'WEIGHTED', 'CUM DEV FROM L YR', 'CUM DEV FROM NORM PRCT', 'CUM DEV FROM L YR PRCT'], skiprows=80, nrows=9, sep=r"[ ]{2,}", engine='python')
    #do something with the df here, for example save it as csv: 
    pd.to_csv(url.split('/')[-1].replace('txt', 'csv'))

【讨论】:

    【解决方案2】:

    您可以使用re 模块解析数据(本示例从第一部分和第一区域创建两个数据框)

    import re
    import requests
    import pandas as pd
    
    
    url = "https://ftp.cpc.ncep.noaa.gov/htdocs/products/analysis_monitoring/cdus/degree_days/archives/Heating%20degree%20Days/weekly%20states/2021/Mar%2020,%202021.txt"
    txt = requests.get(url).text
    
    r_first_section = re.compile(r"(.*?)^\s*REGION", flags=re.S | re.M)
    r_second_section = re.compile(r"^\s*REGION(.*?)^\s+$", flags=re.S | re.M)
    r_row = re.compile(r"^ *[A-Z ]+?(?: +[\-\d]+){8} *$", flags=re.M)
    
    first_section = r_first_section.search(txt).group(1)
    second_section = r_second_section.search(txt).group(1)
    
    data = []
    for row in r_row.findall(first_section):
        data.append(row.strip().rsplit(maxsplit=8))
    
    df1 = pd.DataFrame(data)
    
    data = []
    for row in r_row.findall(second_section):
        data.append(row.strip().rsplit(maxsplit=8))
    
    df2 = pd.DataFrame(data)
    
    print(df1)
    print(df2)
    

    打印:

                       0    1    2     3     4     5     6     7     8
    0            ALABAMA   39  -37    21  2147  -401   235   -16    12
    1             ALASKA  356   62    68  8372  -552   313    -6     4
    2            ARIZONA   83   22     4  1853   -43    70    -2     4
    3           ARKANSAS   67  -29   -19  3077   -70   282    -2    10
    4         CALIFORNIA  117   36    -6  1944  -126    52    -6     3
    5           COLORADO  222   18    34  5473  -427    15    -7     0
    6        CONNECTICUT  210   21    54  4527  -481   105   -10     2
    7           DELAWARE  160   11    54  3494  -534   172   -13     5
    8   DISTRCT COLUMBIA  131    6    50  3140  -393   239   -11     8
    9            FLORIDA    7   -9     7   477  -181   125   -28    36
    10           GEORGIA   54  -25    25  2252  -320   192   -12     9
    11            HAWAII    0    0     0     1     1     0  -999  -999
    12             IDAHO  162  -17   -22  5289  -330  -139    -6    -3
    13          ILLINOIS  177   -8     4  5084  -289   215    -5     4
    14           INDIANA  161  -10     1  4715  -285   274    -6     6
    15              IOWA  193   -7    -7  5929  -102   232    -2     4
    16            KANSAS  133  -10   -12  4366   -91   197    -2     5
    17          KENTUCKY  102  -30   -11  3707  -279   296    -7     9
    18         LOUISIANA   31  -13    26  1621   -46   258    -3    19
    19             MAINE  272   33    40  5838  -617  -115   -10    -2
    20          MARYLAND  161   12    52  3748  -391   267    -9     8
    21     MASSACHUSETTS  226   27    52  4742  -472    68    -9     1
    22          MICHIGAN  203   -9     8  5322  -403   238    -7     5
    23         MINNESOTA  208  -43   -40  6806  -558   -80    -8    -1
    24       MISSISSIPPI   34  -34    17  2130  -206   245    -9    13
    25          MISSOURI  135  -12   -10  4414  -122   199    -3     5
    26           MONTANA  184  -35  -115  6205  -468  -143    -7    -2
    27          NEBRASKA  173  -12   -23  5257  -312   122    -6     2
    28            NEVADA  135   32    -6  3205     5   130     0     4
    29     NEW HAMPSHIRE  252   25    45  5596  -612     2   -10     0
    30        NEW JERSEY  187   17    55  4169  -382   197    -8     5
    31        NEW MEXICO  147   13    24  3880  -188    56    -5     1
    32          NEW YORK  213   19    54  4469  -570    84   -11     2
    33    NORTH CAROLINA  104    1    47  2872  -230   291    -7    11
    34      NORTH DAKOTA  202  -67  -101  7020  -884  -524   -11    -7
    35              OHIO  166  -12    11  4589  -410   339    -8     8
    36          OKLAHOMA   85  -18   -12  3453    89   362     3    12
    37            OREGON  171   35    -4  3926   -70  -176    -2    -4
    38      PENNSYLVANIA  186    5    41  4510  -416   209    -8     5
    39      RHODE ISLAND  215   27    54  4406  -339    73    -7     2
    40    SOUTH CAROLINA   72   -6    37  2313  -209   225    -8    11
    41      SOUTH DAKOTA  202  -20   -32  5986  -572  -187    -9    -3
    42         TENNESSEE   68  -44   -12  3323  -181   288    -5     9
    43             TEXAS   41   -7    31  1725  -131   211    -7    14
    44              UTAH  163  -14     5  5102  -288  -137    -5    -3
    45           VERMONT  279   34    58  6181  -457    82    -7     1
    46          VIRGINIA  143    8    52  3464  -377   269   -10     8
    47        WASHINGTON  158   14   -23  4177  -171   -73    -4    -2
    48     WEST VIRGINIA  135  -20     6  4157  -300   337    -7     9
    49         WISCONSIN  205  -23    -8  6092  -355   154    -6     3
    50           WYOMING  232    9    -2  6219  -406  -193    -6    -3
                     0    1    2    3     4     5    6    7   8
    0      NEW ENGLAND  230   26   51  4903  -490   55   -9   1
    1  MIDDLE ATLANTIC  199   14   50  4418  -484  147  -10   3
    2      E N CENTRAL  181  -12    5  5082  -351  252   -6   5
    3      W N CENTRAL  170  -21  -23  5473  -286   86   -5   2
    4   SOUTH ATLANTIC   77   -6   30  2226  -272  213  -11  11
    5      E S CENTRAL   63  -37    2  2908  -266  269   -8  10
    6      W S CENTRAL   47  -11   21  2015   -89  240   -4  14
    7         MOUNTAIN  153   11    4  4040  -225    4   -5   0
    8          PACIFIC  127   33   -8  2406  -129   17   -5   1
    

    【讨论】:

      猜你喜欢
      • 2021-10-15
      • 1970-01-01
      • 2017-05-16
      • 1970-01-01
      • 2019-03-10
      • 1970-01-01
      • 1970-01-01
      • 2019-06-27
      • 1970-01-01
      相关资源
      最近更新 更多