Ряд TypeError при использовании Pandas с listdir () или транспонированной вставки в DataFrame - PullRequest
0 голосов
/ 07 сентября 2018

Короче говоря, у меня есть DataFrame, который содержит один столбец путей к папкам, и я хочу проверить каждую, что каждая папка существует (возвращая «статус»), и «количество» файлов, содержащихся в ней.Затем поля «status» и «count» добавляются к фрейму данных.

Я пробовал два подхода (см. Комментарии в коде с ***).

  1. Код, как написано ниже, не использует метод "map" и приводит кa TypeError.
  2. Тот же код с нескомментированной (и другими закомментированными) функцией «map» выполняется, но вставляет транспонированные значения status / count.

Вот полный пример кодаэто создает ошибку:

from pandas import DataFrame
import os

#create a couple folders/files, if not already existing
try:
    os.mkdir(r'testfolder1')
    with open(r'testfolder1\testfile1.txt','w') as f1:
        f1.write('test text.')
    os.mkdir(r'testfolder2')
    with open(r'testfolder2\testfile2.txt','w') as f1:
        f1.write('test text.')
    with open(r'testfolder2\testfile3.txt','w') as f1:
        f1.write('test text.')
except FileExistsError:
    print('Folders and/or files already exist.')



class myclass:

    def __init__(self):
        self.df = DataFrame(['testfolder1','testfolder2'],columns=['path'])

    def repo_check(self):
        """gather status and size of each repo path"""

        def dir_check(path):
            '''checks for existence of directory and count of items within'''
            try:
                itemcount = len(os.listdir(path))
                result = ['found', itemcount]
            except FileNotFoundError:
                result = ['not found', 0]
            return result

        #Add status of each repo and count of contents to df
        #self.df['status'], self.df['count'] = self.df.path.map(dir_check)     #***ALTERNATE APPROACH - RESULTS IN "TRANSPOSED" INSERTION INTO DATAFRAME***
        self.df['status'], self.df['count'] = dir_check(self.df.path)
        print(self.df)      #***RESULTS IN TYPEERROR***


data = myclass()                #instantiate class
print('Created dataframe:')
print(data.df)                  #print original dataframe

print()
print('New dataframe:')
data.repo_check()               #calculates and adds calculated columns to df
print(data.df)                  #print new dataframe with calculated columns

Подход № 1 приводит к следующему выводу:

Created dataframe:
          path
0  testfolder1
1  testfolder2

New dataframe:
Traceback (most recent call last):
  File "C:/Users/B1457080/Documents/Python/_misc/pandas_map_test/pandas_map_test2.py", line 56, in <module>
    data.repo_check()               #calculates and adds calculated columns to df
  File "C:/Users/B1457080/Documents/Python/_misc/pandas_map_test/pandas_map_test2.py", line 46, in repo_check
    self.df['status'], self.df['count'] = dir_check(self.df.path)
  File "C:/Users/B1457080/Documents/Python/_misc/pandas_map_test/pandas_map_test2.py", line 38, in dir_check
    itemcount = len(os.listdir(path))
TypeError: listdir: path should be string, bytes, os.PathLike or None, not Series

Process finished with exit code 1

Подход № 2 приводит к следующему выводу (транспонированные значения состояния / количества):

Created dataframe:
          path
0  testfolder1
1  testfolder2

New dataframe:
          path status  count
0  testfolder1  found  found
1  testfolder2      1      2
          path status  count
0  testfolder1  found  found
1  testfolder2      1      2

Process finished with exit code 0

Как ни странно, если я выполняю аналогично структурированную операцию с функцией, основанной на математике, а не на методе os.listdir (), он НЕ транспонирует вставленные значения:

from pandas import DataFrame

class myclass:

    def __init__(self):
        self.df = DataFrame([[1,2,3],[4,5,6]],columns=['alpha','beta','gamma'])

    def test_classmethod(self):
        def test_function(x):
            return [x**2, x**.5]        #returns a two-element list to be insterted in the df row

        #Add two columns for computing square and sqrt (both methods below work)
        #self.df['gamma^2'], self.df['gamma^0.5'] = self.df['gamma'].map(test_function)
        self.df['gamma^2'], self.df['gamma^0.5'] = test_function(self.df['gamma'])


data = myclass()                #instantiate class
print('Created dataframe:')
print(data.df)                  #print original dataframe

print()
print('New dataframe:')
data.test_classmethod()         #calculates and adds calculated columns to df
print(data.df)                  #print new dataframe with calculated columns

Это дает:

Created dataframe:
   alpha  beta  gamma
0      1     2      3
1      4     5      6

New dataframe:
   alpha  beta  gamma  gamma^2  gamma^0.5
0      1     2      3        9   1.732051
1      4     5      6       36   2.449490

Будем благодарны за любые предложения о том, как заставить Подход 1 или Подход 2 работать как задумано!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...