Mais

Atributos de junção por local não parecem incluir dados que deveriam

Atributos de junção por local não parecem incluir dados que deveriam


Estou tentando calcular o número de paradas de ônibus que ficam a 400 m de c. 100 propriedades que estão relativamente próximas umas das outras.

Usando o MMQIS, criei o buffer de 400m para as propriedades, o que foi bom, mas quando eles foram exibidos, percebi que alguns se sobrepunham. Em seguida, executei uma 'junção de atributos por localização', selecionando minha camada de ponto de ônibus como a camada de vetor de destino e a camada de buffer de 400m como a 'camada de junção de vetor', e rapidamente combinou os dois conjuntos de dados. Inicialmente, pensei que essa sequência de eventos estava correta, mas quando filtro alguns dos buffers individuais que se sobrepõem, fica claro que o conjunto de dados combinado não inclui todos os dados de ponto de ônibus que aparecem na camada de ponto de ônibus. E todas as camadas têm o mesmo CRS.

Estou perdendo um truque? Preciso encontrar a resposta o mais rápido possível. Existe uma maneira simples de fazer isso se estiver além das capacidades de associação de atributos por local?


Se eu entendi a descrição do seu problema corretamente, o Pontos no polígono ferramenta deve calcular diretamente o número de paradas de ônibus (pontos) dentro de 400 metros de cada recurso de entrada (buffer).


OK, fiz progressos com isso - foi uma experiência um pouco dolorosa, mas agora tenho as respostas que quero. Tenho certeza de que há uma abordagem mais refinada para resolver isso, então, por favor, dê um passo à frente se você tiver uma sugestão, mas para compartilhar com você, fiz o seguinte:

  1. Realizei uma 'camada de divisão vetorial' na minha camada de buffer de 400m,
    que criou mais de 100 shapefiles e eu os despejei em sua própria pasta
  2. Localize os 'atributos de junção por local' na caixa de ferramentas de processamento e clique com o botão direito e selecione 'executar como processo em lote'. Em seguida, preenchi a tabela que apareceu com os shapefiles de buffer individuais e o arquivo da camada de parada de ônibus - foi um processo lento devido à quantidade de arquivos que eu tinha, mas quando apertei o botão de execução a coisa fez o que eu queria.
  3. Então, eu tinha mais de 100 arquivos de saída que precisava mesclar. No final, decidi que a melhor maneira de fazer isso era combinar os arquivos dbf separados em um único arquivo dbf no Excel. Fiz isso usando as instruções abaixo - todo o crédito por isso vai para alguém chamado Brian Johnson que postou isso no site da ESRI, a quem estendo meus agradecimentos

Esta é uma solução VBA do Excel. Espero que o código seja comentado o suficiente para ser seguido.

1) Abra uma nova pasta de trabalho do Excel. 2) Vá para o Editor do VBA e insira um 'Módulo'. 3) Cole o código mostrado abaixo no Módulo. 4) Salve esta pasta de trabalho do Excel (como um XLSM se estiver usando o Excel 2007 ou superior). 5) Mude a atribuição do FolderPath para a pasta com seus arquivos DBF. 6) Execute o sub Merge_DBF_Files. 7) Você pode usar a lista Coluna A de nomes de arquivo de origem para criar uma fórmula do Excel para extrair os dados necessários do nome do arquivo usando FIND, MID, etc. Exclua outras colunas de campo DBF desnecessárias.

Eu testei isso em um pequeno conjunto de DBFs e funciona bem. Não tenho certeza de como funcionará com 1.000 arquivos ...

Brian Johnson

Sub Merge_DBF_Files () 'Rotina VBA para mesclar todos os arquivos DBF em uma pasta em uma planilha Excel' Brian Johnson '[email protected]' 12/02/14 Dim SummarySheet As Worksheet, WorkBk As Workbook Dim NRow As Long, FileName As String Dim SourceRange As Range, DestRange As Range Dim FolderPath As String 'Crie uma nova pasta de trabalho e defina uma variável para a primeira planilha. Set SummarySheet = Workbooks.Add (xlWBATWorksheet) .Worksheets (1) 'Modifica o caminho desta pasta para apontar para os arquivos que deseja usar. FolderPath = "C:  temp  DBF_Files " 'NRow controla onde inserir novas linhas na pasta de trabalho de destino. NRow = 1 i = 0 'Chame Dir pela primeira vez, apontando-o para todos os arquivos DBF no caminho da pasta. FileName = Dir (FolderPath & "* .dbf") 'Loop até que Dir retorne uma string vazia. Do While FileName <> "" 'Abra uma pasta de trabalho na pasta Set WorkBk = Workbooks.Open (FolderPath & FileName) Debug.Print Format (i, "00") & ":" & FolderPath & FileName' Defina a célula na coluna A para ser o nome do arquivo. SummarySheet.Range ("A" & NRow) .Value = "FileName" 'Definir o intervalo de origem WorkBk.Worksheets (1) .Activate RowCount = Application.CountA (Range ("A: A")) Definir SourceRange = WorkBk.Worksheets (1) .Range ("A1: BB" & RowCount) SummarySheet.Range ("A" & NRow + 1 & ": A" & (RowCount + NRow - 1)). Value = FileName 'Defina o intervalo de destino para iniciar na coluna B e ter o mesmo tamanho que o intervalo de origem. Set DestRange = SummarySheet.Range ("B" & NRow) Set DestRange = DestRange.Resize (SourceRange.Rows.Count, SourceRange.Columns.Count) 'Copiar sobre os valores da origem para o destino. DestRange.Value = SourceRange.Value 'Aumente NRow para que saibamos para onde copiar os dados a seguir. NRow = NRow + DestRange.Rows.Count 'Fechar a pasta de trabalho de origem sem salvar as alterações. WorkBk.Close savechanges: = False 'Use Dir para obter o próximo nome de arquivo. FileName = Dir () i = i + 1 Loop 'Chame AutoFit na planilha de destino para que todos os dados sejam legíveis. SummarySheet.Columns.AutoFit End Sub

Se você gostaria de fazer a etapa 3 no QGIS, você pode usar a ferramenta "Merge Shapefiles to One" no menu Vector> Ferramentas de gerenciamento de dados. Ele permite que você selecione uma pasta e um tipo de geometria e mescla todos os arquivos na pasta especificada.


Eager table join carregando no typeorm

Eu quero ser capaz de carregar antecipadamente uma lista de usuários e também carregar criaturas que são de propriedade deste usuário.

Aqui estão minhas tabelas de usuário / criatura / criatura do usuário:

O problema é que não consigo descobrir uma maneira de carregar antecipadamente uma lista de usuários e criaturas que pertencem a um usuário. Aqui está um exemplo de como eu faria isso em sequência:

Agora, como devo fazer a coisa acima no typeorm?

Agradeço antecipadamente pelo seu tempo.


Embora não pareça haver muitas regras rígidas e rápidas, há algumas boas diretrizes mencionadas na postagem. Por exemplo, uma das recomendações é usar elementos quando seus dados não devem ser normalizados para espaço em branco, pois os processadores XML podem normalizar os dados dentro de um atributo, modificando assim o texto bruto.

De vez em quando, me pego me referindo a este artigo, enquanto desenvolvo várias estruturas XML. Esperançosamente, isso será útil para outras pessoas também.

Princípio do conteúdo central

Se você considerar que as informações em questão fazem parte do material essencial que está sendo expresso ou comunicado no XML, coloque-as em um elemento. Para documentos legíveis por humanos, isso geralmente significa o conteúdo principal que está sendo comunicado ao leitor. Para formatos de registros orientados à máquina, isso geralmente significa os dados que vêm diretamente do domínio do problema. Se você considerar as informações como periféricas ou incidentais à comunicação principal, ou puramente destinadas a ajudar os aplicativos a processar a comunicação principal, use os atributos. Isso evita entulhar o conteúdo do núcleo com material auxiliar. Para formatos de registros orientados à máquina, isso geralmente significa notações específicas do aplicativo nos dados principais do domínio do problema.

Como exemplo, vi muitos formatos XML, geralmente desenvolvidos em empresas, onde os títulos dos documentos eram colocados em um atributo. Acho que um título é uma parte tão fundamental da comunicação de um documento que deve estar sempre no conteúdo do elemento. Por outro lado, tenho visto frequentemente casos em que identificadores internos de produto foram colocados como elementos em registros descritivos do produto. Em alguns desses casos, os atributos eram mais apropriados porque o código de produto interno específico não seria de interesse primário para a maioria dos leitores ou processadores do documento, especialmente quando o ID era de um formato muito longo ou inescrutável.

Você deve ter ouvido o princípio de que dados vão em elementos, metadados em atributos. Os dois parágrafos anteriores realmente expressam o mesmo princípio, mas em uma linguagem mais deliberada e menos confusa.

Princípio da informação estruturada

Se a informação for expressa em uma forma estruturada, especialmente se a estrutura puder ser extensível, use elementos. Por outro lado: se a informação for expressa como um token atômico, use atributos. Elementos são o mecanismo extensível para expressar estrutura em XML. Quase todas as ferramentas de processamento XML são projetadas em torno desse fato e, se você dividir as informações estruturadas de maneira adequada em elementos, descobrirá que suas ferramentas de processamento complementam seu design e, com isso, ganha produtividade e facilidade de manutenção. Os atributos são projetados para expressar propriedades simples das informações representadas em um elemento. Se você trabalhar contra a arquitetura básica do XML, agrupando informações estruturadas em atributos, poderá obter certa concisão e conveniência especiosas, mas provavelmente pagará pelos custos de manutenção.

As datas são um bom exemplo: uma data tem uma estrutura fixa e geralmente atua como um único token, por isso faz sentido como um atributo (de preferência expresso em ISO-8601). A representação de nomes pessoais, por outro lado, é um caso em que vi esse princípio surpreender os designers. Vejo muitos nomes em atributos, mas sempre argumentei que nomes pessoais deveriam estar no conteúdo do elemento. Um nome pessoal tem uma estrutura surpreendentemente variável (em algumas culturas, você pode causar confusão ou ofensa ao omitir títulos honoríficos ou assumir uma ordem das partes dos nomes). Um nome pessoal também raramente é um token atômico. Por exemplo, às vezes você pode querer pesquisar ou classificar por um nome próprio e às vezes por um sobrenome. Devo salientar que é tão problemático colocar um nome completo no conteúdo de um único elemento quanto colocá-lo em um atributo.


Por que seu modelo não está generalizando corretamente?

A parte mais importante é entender Por quê sua rede não generaliza bem. Modelos de aprendizado de máquina de alta capacidade têm a capacidade de memorizar o conjunto de treinamento, que pode levar a sobreajuste.

Overfitting é o estado em que um estimador começou a aprender o conjunto de treinamento tão bem que começou a modelar o ruído nas amostras de treinamento (além de todos os relacionamentos úteis).

Por exemplo, na imagem abaixo podemos ver como a linha azul claramente se ajustou demais.


Definindo a cultura do seu local de trabalho

A maioria de nós permite que nossa cultura de trabalho se forme naturalmente, sem definir o que queremos que seja, e isso é um erro. Por exemplo:

  • Criamos políticas e programas no local de trabalho com base no que outros empregadores fazem e se eles se encaixam em nosso ambiente de trabalho.
  • Contratamos funcionários que não se enquadram.
  • Toleramos estilos de gestão que ameaçam o engajamento e a retenção dos funcionários.
  • Não criamos e comunicamos uma missão, visão e conjunto de valores claros e inspiradores.
  • Nossos ambientes de trabalho são sem brilho.
  • Não consideramos como nossas ações diárias (ou omissões) como líderes estão afetando a formação de nossa cultura.

Por essas razões, é importante dar um passo atrás, avaliar e definir sua cultura de local de trabalho - tanto o que é agora como o que você deseja que seja no futuro - e como todos esses fatores contribuem ou prejudicam sua cultura desejada.

Embora possa ser muito difícil de definir, as ferramentas de avaliação e pesquisas podem ajudá-lo a avaliar sua cultura. Eles podem revelar lacunas entre a cultura que você deseja atingir e a cultura que você possui atualmente.

Além disso, a observação, o exame do comportamento no local de trabalho, reuniões, discussões e entrevistas podem expor o clima do seu local de trabalho. O importante é começar de algum lugar e abrir um diálogo com sua equipe de liderança sobre isso.

Lembre-se de que a cultura é sempre um trabalho em andamento. Isso pode e vai mudar. Torne a cultura tão importante quanto sua estratégia de negócios. É muito significativo para ignorar e moldá-lo é uma das suas responsabilidades mais importantes como líderes e profissionais de RH.

A ERC Consulting fornece serviços de seleção de funcionários para organizações em todo o país.

Postagens Relacionadas

O local de trabalho tem um impacto significativo na saúde dos funcionários e, da mesma forma, a saúde dos funcionários tem a.

De acordo com um relatório de pesquisa da McKinsey & amp Company, 40% das mulheres (em comparação com 11% dos homens) em 2016.

Na ERC, acreditamos que criar um ótimo local de trabalho é criar um ambiente e uma cultura.

Receba atualizações por e-mail

Nunca perca uma atualização. Inscreva-se para receber e-mails semanais com nossas últimas postagens.


Exibir anúncios para seu público-alvo

Seus anúncios podem ser exibidos especificamente para clientes em trânsito, que usam seus smartphones e tablets para pesquisar e navegar na Internet. Ou você pode criar anúncios que aparecem em desktops e smartphones, mas priorizar onde deseja que os anúncios apareçam com mais frequência.

Você pode exibir seus anúncios para clientes em locais específicos, como cidades ou países. Por exemplo, Pat deseja que apenas clientes locais vejam seus anúncios. Eles podem configurar seus anúncios para serem exibidos aos clientes em um raio de 20 milhas ao redor de sua loja usando a segmentação por raio.

Você também pode configurar seus anúncios para serem exibidos para usuários de uma determinada faixa etária ou sexo, ou para serem exibidos em um determinado dia e hora da semana. Para obter mais informações sobre como exibir anúncios para seu público-alvo, consulte Exibir anúncios para seu público-alvo.


2 respostas 2

Seria recomendável ter o cabeçalho HSTS definido em cada resposta HTTPS, mas isso fornece efetivamente o mesmo nível de segurança, porque a política HSTS é armazenada em cache por segundos de idade máxima. É definido que a falta do cabeçalho Strict-Transport-Security não causa a exclusão da política, mas apenas configura um valor zero para a idade máxima (RFC 6796 6.1.1, 5.3 e 12.5). Além disso, definir um valor muito baixo faz com que ele expire muito cedo.

Essas configurações podem proteger um usuário que visitou a página em uma rede confiável (ou um navegador viu o cabeçalho HSTS nele, para ser mais preciso) dentro dos segundos de idade máxima. Se os URLs que fornecem o cabeçalho HSTS forem carregados em todas as visitas, isso não comprometeria isso. Apesar disso, não consigo ver nenhum motivo não para mover essa configuração no nível do nome do host, e pode ser apenas um erro também.

No entanto, este impede de proteger os usuários antes eles já visitaram o site (que seria a próxima etapa e nível de amp), como a presença de Strict-Transport-Security com includeSubDomains e pré-carregamento mediante solicitação para / é obrigatório, se você deseja adicionar o domínio a uma lista pré-carregada do HSTS. Essa é a única maneira de proteger o example.com, * .example.com, *. *. Example.com etc. inteiro com antecedência. Além disso, hstspreload.org exige que a idade máxima seja de pelo menos 31536000 segundos (1 ano).

Parece estranho. Aqui estão dois cenários para ilustrar.

Cenário Um

Talvez as configurações do navegador possam fazer com que os ativos não sejam carregados, por exemplo, um dispositivo móvel em dados móveis, onde os ativos podem não ser carregados para conservar a largura de banda.

Então você estaria aberto a todas as vulnerabilidades contra as quais o HSTS protege.

Cenário Dois (Este cenário editado após discussão nos comentários abaixo)

Além disso, mesmo sem essa restrição no carregamento de ativos, sem o cabeçalho HSTS para a página de índice, você deixa seu aplicativo da web aberto a ataques, cujo resultado é que um invasor já pode ter conseguido substituir a resposta inicial por uma página arbitrária de sua escolha, em vez de http. Se isso acontecer para o carregamento da página de índice, qualquer carregamento de ativo que deve acontecer a seguir se tornará irrelevante, de modo que seu navegador nem mesmo solicitará esses ativos e nunca verá o cabeçalho HSTS nas respostas.

Como um exemplo concreto, considere um ataque man-in-the-middle (MiTM) de remoção de SSL. Com ataques MiTM de remoção de SSL, uma conexão https é convertida em http pelo MiTM. Agora, o que evita que o invasor simplesmente ignore o cabeçalho HSTS proveniente de seu aplicativo web, sua resposta e apresente sua resposta arbitrária de volta ao cliente por http sem o cabeçalho HSTS? É aí que as listas de pré-carregamento entram em cena.

Todos os principais navegadores implementam listas de pré-carregamento de HSTS que incluem sites conhecidos que oferecem suporte a HSTS. Assim, o navegador não precisa depender do recebimento da resposta real do site para saber que ele implementa o HSTS, portanto, o navegador obrigará o uso de https. Então, como essas listas de pré-carregamento do HSTS são geradas para uso pelos navegadores?

No caso do firefox, por exemplo (consulte blog.mozilla.org/security),

Para construir nossa lista de pré-carregamento, uma solicitação é enviada a cada host com ‘modo:“ force-https ”‘ na lista do Chrome. Somente se um host responder com um cabeçalho HSTS válido.

portanto, não incluir o cabeçalho HSTS na página de índice do aplicativo da web pode fazer com que ele seja excluído da lista de pré-carregamento, deixando o aplicativo da web aberto a ataques contra os quais o HSTS (implementado com listas de pré-carregamento) normalmente protegeria.


É mais fácil começar com a segunda pergunta e depois passar para a primeira.

Random Forest é um algoritmo de bagging. Reduz a variância.

Digamos que você tenha modelos pouco confiáveis, como Árvores de Decisão. (Por que não confiável? Porque se você alterar seus dados um pouco, a árvore de decisão criada pode ser muito diferente.) Nesse caso, você pode construir um modelo robusto (reduzir a variância) por meio de ensacamento - bagging é quando você cria modelos diferentes, reamostrando seus dados para tornar o modelo resultante mais robusto.

Floresta aleatória é o que chamamos de ensacamento aplicado a árvores de decisão, mas não é diferente de outro algoritmo de ensacamento.

Por que você quer fazer isso? Depende do problema. Mas, geralmente, é altamente desejável que o modelo seja estável.

O reforço reduz a variância e também reduz o viés. Isso reduz a variância porque você está usando vários modelos (ensacamento). Ele reduz o preconceito treinando o modelo subsequente, dizendo-lhe quais erros os modelos anteriores cometeram (a parte de reforço).

Existem dois algoritmos principais:

  • Adaboost: este é o algoritmo original que você diz aos modelos subsequentes para punir mais fortemente as observações erradas pelos modelos anteriores
  • Aumento de gradiente: você treina cada modelo subsequente usando os resíduos (a diferença entre os valores previstos e verdadeiros)

Nestes conjuntos, seu aluno base devo seja fraco. Se superajustar os dados, não haverá resíduos ou erros para os modelos subsequentes se basearem. Por que esses modelos são bons? Bem, a maioria das competições em sites como o Kaggle foram vencidas usando árvores de aumento de gradiente. A ciência de dados é uma ciência empírica, "porque funciona" é bom o suficiente. De qualquer forma, observe que os modelos de boost podem super ajustar (embora empiricamente não seja muito comum).

Outra razão pela qual o aumento de gradiente, em particular, também é muito legal: porque torna muito fácil usar diferentes funções de perda, mesmo quando a derivada não é convexa. Por exemplo, ao usar a previsão probabilística, você pode usar coisas como a função pinball como sua função de perda, algo que é muito mais difícil com redes neurais (porque a derivada é sempre constante).

[Nota histórica interessante: Boosting foi originalmente uma invenção teórica motivada pela questão "podemos construir um modelo mais forte usando modelos mais fracos"]

Aviso: as pessoas às vezes confundem floresta aleatória com árvores de aumento de gradiente, apenas porque ambas usam árvores de decisão, mas são duas famílias de conjuntos muito diferentes.


Atributos de associação por localização não parecem incluir dados que deveriam - Sistemas de Informação Geográfica

Sondar um PDF para obter informações detalhadas sobre cada caractere de texto, retângulo e linha. Mais: extração de tabela e depuração visual.

Funciona melhor em PDFs gerados por máquina, em vez de digitalizados. Construído em pdfminer.six.

Para relatar um bug ou solicite um recurso, registre um problema. Fazer uma pergunta ou solicitar ajuda com um PDF específico, use o fórum de discussões.

A saída será um CSV contendo informações sobre cada caractere, linha e retângulo no PDF.

Argumento Descrição
--format [formato] csv ou json. O formato json retorna mais informações; inclui metadados em nível de PDF e nível de página, além de atributos aninhados em dicionário.
--pages [lista de páginas] Uma lista de páginas delimitada por espaço e indexada por 1 ou intervalos de páginas hifenizados. Por exemplo, 1, 11-15, que retornaria dados para as páginas 1, 11, 12, 13, 14 e 15.
--types [lista de tipos de objetos a serem extraídos] As opções são char, rect, line, curve, image, annot, etc. O padrão é todos disponíveis.
--laparams Uma string formatada em JSON (por exemplo, '<"detect_vertical": true>') para passar para pdfplumber.open (. Laparams =.).

Para começar a trabalhar com um PDF, chame pdfplumber.open (x), onde x pode ser um:

  • caminho para o seu arquivo PDF
  • objeto de arquivo, carregado como bytes
  • objeto semelhante a um arquivo, carregado como bytes

O método open retorna uma instância da classe pdfplumber.PDF.

Para carregar um PDF protegido por senha, passe o argumento de palavra-chave de senha, por exemplo, pdfplumber.open ("arquivo.pdf", senha = "teste").

Para definir parâmetros de análise de layout para o mecanismo de layout de pdfminer.six, passe o argumento de palavra-chave laparams, por exemplo, pdfplumber.open ("file.pdf", laparams = <"line_overlap": 0.7>).

Valores de metadados inválidos são tratados como um aviso por padrão. Se não for essa a intenção, passe strict_metadata = True para o método aberto e pdfplumber.open gerará uma exceção se não for capaz de analisar os metadados.

A classe pdfplumber.PDF de nível superior representa um único PDF e tem duas propriedades principais:

Propriedade Descrição
.metadata Um dicionário de pares chave / valor de metadados, extraído dos trailers de informações do PDF. Normalmente inclui "CreationDate", "ModDate", "Produtor" etc.
.Páginas Uma lista contendo uma instância de pdfplumber.Page por página carregada.

A classe pdfplumber.Page está no cerne do pdfplumber. A maioria das coisas que você fará com o pdfplumber girará em torno dessa classe. Possui estas propriedades principais:

Propriedade Descrição
.número de página O número da página sequencial, começando com 1 para a primeira página, 2 para a segunda e assim por diante.
.largura A largura da página.
.altura A altura da página.
.objects / .chars / .lines / .rects / .curves / .images Cada uma dessas propriedades é uma lista e cada lista contém um dicionário para cada um desses objetos embutidos na página. Para obter mais detalhes, consulte "Objetos" abaixo.

Método Descrição
.crop (bounding_box, relative = False) Retorna uma versão da página cortada na caixa delimitadora, que deve ser expressa como 4 tuplas com os valores (x0, topo, x1, fundo). As páginas cortadas retêm objetos que caem, pelo menos parcialmente, dentro da caixa delimitadora. Se um objeto cair apenas parcialmente dentro da caixa, suas dimensões serão fatiadas para caber na caixa delimitadora. Se relative = True, a caixa delimitadora é calculada como um deslocamento do canto superior esquerdo da caixa delimitadora da página, em vez de um posicionamento absoluto. (Consulte a edição 245 para obter um exemplo visual e uma explicação.)
.within_bbox (bounding_box, relative = False) Semelhante a .crop, mas retém apenas objetos que caem inteiramente dentro da caixa delimitadora.
.filter (test_function) Retorna uma versão da página com apenas os .objects para os quais test_function (obj) retorna True.
.dedupe_chars (tolerância = 1) Retorna uma versão da página com caracteres duplicados - aqueles que compartilham o mesmo texto, nome da fonte, tamanho e posicionamento (dentro da tolerância x / y) que outros caracteres - removidos. (Veja a edição 71 para entender a motivação.)
.extract_text (x_tolerance = 3, y_tolerance = 3) Agrupa todos os objetos de caractere da página em uma única string. Adiciona espaços onde a diferença entre x1 de um caractere e x0 do próximo é maior que x_tolerance. Adiciona caracteres de nova linha em que a diferença entre o doctop de um caractere e o doctop do próximo é maior que y_tolerance.
.extract_words (x_tolerance = 3, y_tolerance = 3, keep_blank_chars = False, use_text_flow = False, horizontal_ltr = True, vertical_ttb = True, extra_attrs = []) Retorna uma lista de todas as coisas que parecem palavras e suas caixas delimitadoras. As palavras são consideradas sequências de caracteres onde (para caracteres "verticais") a diferença entre x1 de um caractere e x0 do próximo é menor ou igual a x_tolerance e onde o doctop de um caractere e o doctop do próximo é menor ou igual a y_tolerance. Uma abordagem semelhante é feita para caracteres não verticais, mas em vez disso medindo as distâncias verticais, em vez de horizontais, entre eles. Os parâmetros horizontal_ltr e vertical_ttb indicam se as palavras devem ser lidas da esquerda para a direita (para palavras horizontais) / de cima para baixo (para palavras verticais). Alterar keep_blank_chars para True significa que os caracteres em branco são tratados como parte de uma palavra, não como um espaço entre as palavras. Alterar use_text_flow para True usará o fluxo de caracteres subjacente do PDF como um guia para ordenar e segmentar as palavras, em vez de pré-classificar os caracteres pela posição x / y. (Isso simula como arrastar um cursor destaca o texto em um PDF, com isso, a ordem nem sempre parece ser lógica.) Passar uma lista de extra_attrs (por exemplo, ["nome da fonte", "tamanho"] restringirá cada palavra a caracteres que compartilham exatamente o mesmo valor para cada um desses atributos, e a palavra dicts resultante indicará esses atributos.
.extract_tables (table_settings) Extrai dados tabulares da página. Para obter mais detalhes, consulte "Extraindo tabelas" abaixo.
.to_image (** conversion_kwargs) Retorna uma instância da classe PageImage. Para obter mais detalhes, consulte "Depuração visual" abaixo. Para conversion_kwargs, veja aqui.
.perto() Por padrão, os objetos de Página armazenam em cache seu layout e informações de objeto para evitar ter que reprocessá-los. Ao analisar PDFs grandes, no entanto, essas propriedades em cache podem exigir muita memória. Você pode usar este método para liberar o cache e liberar a memória. (Na versão & lt = 0.5.25, use .flush_cache ().)

Cada instância de pdfplumber.PDF e pdfplumber.Page fornece acesso a vários tipos de objetos PDF, todos derivados da análise de PDF pdfminer.six. Cada uma das propriedades a seguir retorna uma lista Python dos objetos correspondentes:

  • .chars, cada um representando um único caractere de texto.
  • .lines, cada uma representando uma única linha unidimensional.
  • .rects, cada um representando um único retângulo bidimensional.
  • .curves, cada uma representando qualquer série de pontos conectados que o pdfminer.six não reconhece como uma linha ou retângulo.
  • .images, cada uma representando uma imagem.
  • .annots, cada um representando uma única anotação de PDF (consulte a Seção 8.4 da especificação oficial do PDF para obter detalhes)
  • .hyperlinks, cada um representando uma única anotação de PDF do subtipo Link e tendo um atributo de ação URI

Cada objeto é representado como um dicionário Python simples, com as seguintes propriedades:

Propriedade Descrição
número de página Número da página em que este personagem foi encontrado.
texto Por exemplo, "z", ou "Z" ou "".
nome da fonte Nome da fonte do personagem.
Tamanho Tamanho da fonte.
adv Igual à largura do texto * o tamanho da fonte * fator de escala.
direito Se o personagem está de pé.
altura Altura do personagem.
largura Largura do personagem.
x0 Distância do lado esquerdo do caractere do lado esquerdo da página.
x1 Distância do lado direito do caractere do lado esquerdo da página.
y0 Distância da parte inferior do caractere da parte inferior da página.
y1 Distância da parte superior do caractere da parte inferior da página.
principal Distância do topo do caractere do topo da página.
inferior Distância da parte inferior do personagem ao topo da página.
doctop Distância do topo do caractere ao topo do documento.
Tipo de objeto "Caracteres"
Propriedade Descrição
número de página Número da página em que esta linha foi encontrada.
altura Altura da linha.
largura Largura da linha.
x0 Distância da extremidade esquerda do lado esquerdo da página.
x1 Distância da extremidade direita do lado esquerdo da página.
y0 Distância da extremidade inferior da parte inferior da página.
y1 Distância da extremidade superior da parte inferior da página.
principal Distância do topo da linha do topo da página.
inferior Distância da parte inferior da linha a partir do topo da página.
doctop Distância do topo da linha ao topo do documento.
espessura da linha Espessura da linha.
Tipo de objeto "linha"
Propriedade Descrição
número de página Número da página em que este retângulo foi encontrado.
altura Altura do retângulo.
largura Largura do retângulo.
x0 Distância do lado esquerdo do retângulo do lado esquerdo da página.
x1 Distância do lado direito do retângulo do lado esquerdo da página.
y0 Distância da parte inferior do retângulo da parte inferior da página.
y1 Distância da parte superior do retângulo da parte inferior da página.
principal Distância do topo do retângulo do topo da página.
inferior Distância da parte inferior do retângulo da parte superior da página.
doctop Distância do topo do retângulo ao topo do documento.
espessura da linha Espessura da linha.
Tipo de objeto "rect"
Propriedade Descrição
número de página Número da página em que esta curva foi encontrada.
pontos Pontos - como uma lista de (x, topo) tuplas - descrevendo a curva.
altura Altura da caixa delimitadora da curva.
largura Largura da caixa delimitadora da curva.
x0 Distância do ponto mais à esquerda da curva do lado esquerdo da página.
x1 Distância do ponto mais à direita da curva do lado esquerdo da página.
y0 Distância do ponto mais baixo da curva da parte inferior da página.
y1 Distância do ponto mais alto da curva da parte inferior da página.
principal Distância do ponto mais alto da curva do topo da página.
inferior Distância do ponto mais baixo da curva do topo da página.
doctop Distância do ponto mais alto da curva da parte superior do documento.
espessura da linha Espessura da linha.
Tipo de objeto "curva"

Além disso, pdfplumber.PDF e pdfplumber.Page fornecem acesso a duas listas derivadas de objetos: .rect_edges (que decompõe cada retângulo em suas quatro linhas) e .edges (que combina .rect_edges com .lines).

Obtenção de objetos de layout de nível superior via pdfminer.six

Se você passar o parâmetro pdfminer.six -handling laparams para pdfplumber.open (.), O dicionário .objects de cada página também conterá os objetos de layout de nível superior de pdfminer.six, como "textboxhorizontal".

Observação: Para usar as ferramentas de depuração visual do pdfplumber, você também precisará ter dois softwares adicionais instalados em seu computador:

Criando um PageImage com .to_image ()

Para transformar qualquer página (incluindo páginas cortadas) em um objeto PageImage, chame my_page.to_image (). Você pode, opcionalmente, passar uma resolução = argumento de palavra-chave, cujo padrão é 72. Ex .:

Objetos PageImage funcionam bem com notebooks IPython / Jupyter, eles renderizam automaticamente como saídas de células. Por exemplo:

Método Descrição
im.reset () Limpa tudo que você desenhou até agora.
im.copy () Copia a imagem para um novo objeto PageImage.
im.save (path_or_fileobject, format = "PNG") Salva a imagem anotada.

Você pode passar coordenadas explícitas ou qualquer objeto PDF pdfplumber (por exemplo, char, line, rect) para esses métodos.

Método de objeto único Método em massa Descrição
im.draw_line (linha, traço =, stroke_width = 1) im.draw_lines (list_of_lines, ** kwargs) Desenha uma linha de uma linha, curva ou 2 tuplas de 2 tuplas (por exemplo, ((x, y), (x, y))).
im.draw_vline (localização, traço =, stroke_width = 1) im.draw_vlines (list_of_locations, ** kwargs) Desenha uma linha vertical na coordenada x indicada pela localização.
im.draw_hline (localização, traço =, stroke_width = 1) im.draw_hlines (list_of_locations, ** kwargs) Desenha uma linha horizontal na coordenada y indicada pela localização.
im.draw_rect (bbox_or_obj, fill =, curso =, stroke_width = 1) im.draw_rects (list_of_rects, ** kwargs) Desenha um retângulo de um retângulo, char, etc., ou caixa delimitadora de 4 tuplas.
im.draw_circle (center_or_obj, radius = 5, fill =, curso =) im.draw_circles (list_of_circles, ** kwargs) Desenha um círculo na coordenada (x, y) ou no centro de um char, ret, etc.

Observação: os métodos acima são baseados nos métodos ImageDraw do Pillow, mas os parâmetros foram ajustados para consistência com a nomenclatura fill / stroke / stroke_width do SVG.

Solução de problemas de ImageMagick em sistemas baseados em Debian

Se você estiver usando o pdfplumber em um sistema baseado em Debian e encontrar um PolicyError, você pode consertá-lo alterando a seguinte linha em /etc/ImageMagick-6/policy.xml:

(Mais detalhes sobre policy.xml disponíveis aqui.)

A abordagem do pdfplumber para detecção de tabelas se baseia fortemente na tese de mestrado de Anssi Nurminen e é inspirada em Tabula. Funciona assim:

  1. For any given PDF page, find the lines that are (a) explicitly defined and/or (b) implied by the alignment of words on the page.
  2. Merge overlapping, or nearly-overlapping, lines.
  3. Find the intersections of all those lines.
  4. Find the most granular set of rectangles (i.e., cells) that use these intersections as their vertices.
  5. Group contiguous cells into tables.

pdfplumber.Page objects can call the following table methods:

Método Descrição
.find_tables(table_settings=<>) Returns a list of Table objects. The Table object provides access to the .cells , .rows , and .bbox properties, as well as the .extract(x_tolerance=3, y_tolerance=3) method.
.extract_tables(table_settings=<>) Returns the text extracted from tudo tables found on the page, represented as a list of lists of lists, with the structure table -> row -> cell .
.extract_table(table_settings=<>) Returns the text extracted from the maior table on the page, represented as a list of lists, with the structure row -> cell . (If multiple tables have the same size — as measured by the number of cells — this method returns the table closest to the top of the page.)
.debug_tablefinder(table_settings=<>) Returns an instance of the TableFinder class, with access to the .edges , .intersections , .cells , and .tables properties.

By default, extract_tables uses the page's vertical and horizontal lines (or rectangle edges) as cell-separators. But the method is highly customizable via the table_settings argument. The possible settings, and their defaults:

Contexto Descrição
"vertical_strategy" Either "lines" , "lines_strict" , "text" , or "explicit" . See explanation below.
"horizontal_strategy" Either "lines" , "lines_strict" , "text" , or "explicit" . See explanation below.
"explicit_vertical_lines" A list of vertical lines that explicitly demarcate cells in the table. Can be used in combination with any of the strategies above. Items in the list should be either numbers — indicating the x coordinate of a line the full height of the page — or line / rect / curve objects.
"explicit_horizontal_lines" A list of horizontal lines that explicitly demarcate cells in the table. Can be used in combination with any of the strategies above. Items in the list should be either numbers — indicating the y coordinate of a line the full height of the page — or line / rect / curve objects.
"snap_tolerance" Parallel lines within snap_tolerance pixels will be "snapped" to the same horizontal or vertical position.
"join_tolerance" Line segments on the same infinite line, and whose ends are within join_tolerance of one another, will be "joined" into a single line segment.
"edge_min_length" Edges shorter than edge_min_length will be discarded before attempting to reconstruct the table.
"min_words_vertical" When using "vertical_strategy": "text" , at least min_words_vertical words must share the same alignment.
"min_words_horizontal" When using "horizontal_strategy": "text" , at least min_words_horizontal words must share the same alignment.
"keep_blank_chars" When using the text strategy, consider " " chars to be partes of words and not word-separators.
"text_tolerance" , "text_x_tolerance" , "text_y_tolerance" When the text strategy searches for words, it will expect the individual letters in each word to be no more than text_tolerance pixels apart.
"intersection_tolerance" , "intersection_x_tolerance" , "intersection_y_tolerance" When combining edges into cells, orthogonal edges must be within intersection_tolerance pixels to be considered intersecting.

Both vertical_strategy and horizontal_strategy accept the following options:

Estratégia Descrição
"lines" Use the page's graphical lines — including the sides of rectangle objects — as the borders of potential table-cells.
"lines_strict" Use the page's graphical lines — but não the sides of rectangle objects — as the borders of potential table-cells.
"text" For vertical_strategy : Deduce the (imaginary) lines that connect the left, right, or center of words on the page, and use those lines as the borders of potential table-cells. For horizontal_strategy , the same but using the tops of words.
"explicit" Only use the lines explicitly defined in explicit_vertical_lines / explicit_horizontal_lines .

Often it's helpful to crop a page — Page.crop(bounding_box) — before trying to extract the table.

Table extraction for pdfplumber was radically redesigned for v0.5.0 , and introduced breaking changes.

Sometimes PDF files can contain forms that include inputs that people can fill out and save. While values in form fields appear like other text in a PDF file, form data is handled differently. If you want the gory details, see page 671 of this specification.

pdfplumber doesn't have an interface for working with form data, but you can access it using pdfplumber 's wrappers around pdfminer .

For example, this snippet will retrieve form field names and values and store them in a dictionary. You may have to modify this script to handle cases like nested fields (see page 676 of the specification).

    . Demonstrates basic visual debugging and table extraction. . Demonstrates how to use visual debugging to find optimal table extraction settings. Also demonstrates Page.crop(. ) and Page.extract_text(. ). . , an example of using Page.extract_text(. ) .

Comparison to other libraries

Several other Python libraries help users to extract information from PDFs. As a broad overview, pdfplumber distinguishes itself from other PDF processing libraries by combining these features:

  • Easy access to detailed information about each PDF object
  • Higher-level, customizable methods for extracting text and tables
  • Tightly integrated visual debugging
  • Other useful utility functions, such as filtering objects via a crop-box

It's also helpful to know what features pdfplumber does não provide:

  • PDF geração
  • PDF modification
  • Optical character recognition (OCR)
  • Strong support for extracting tables from OCR'ed documents

pdfminer.six provides the foundation for pdfplumber . It primarily focuses on parsing PDFs, analyzing PDF layouts and object positioning, and extracting text. It does not provide tools for table extraction or visual debugging.

pymupdf is substantially faster than pdfminer.six (and thus also pdfplumber ) and can generate and modify PDFs, but the library requires installation of non-Python software (MuPDF). It also does not enable easy access to shape objects (rectangles, lines, etc.), and does not provide table-extraction or visual debugging tools.

camelot , tabula-py , and pdftables all focus primarily on extracting tables. In some cases, they may be better suited to the particular tables you are trying to extract.

PyPDF2 and its successor libraries appear no longer to be maintained.

Many thanks to the following users who've contributed ideas, features, and fixes:

Pull requests are welcome, but please submit a proposal issue first, as the library is in active development.


7 Answers 7

In my experience, Seagates have weird numbers for those two SMART attributes. When diagnosing a Seagate I tend to ignore those and look more closely at other fields like Reallocated Sector Count. Of course, when in doubt replace the drive, but even brand new Seagates will have high numbers for those attributes.

For Seagate disks (and possibly some old ones from WD too) the Seek_Error_Rate and Raw_Read_Error_Rate are 48 bit numbers, where the most significant 16 bits are an error count, and the low 32 bits are a number of operations.

So your disk has performed 2440858991 seeks, of which 46 failed. My experience with Seagate drives is that they tend to fail when the number of errors goes over 1000. YMMV.

The "seek error rate" and "raw read error rate" RAW_VALUES are virtually meaningless for anyone but Seagate's support. As others pointed out, raw values of parameters like "reallocated sector count" or entries in the drive's error log are more likely to indicate a higher probability of failure.

But you can take a look at the interpreted data in the VALUE, WORST and THRESH columns which are meant to be read as gauges:

Meaning that your seek error rate is currently considered to be "77% good" and is reported as a problem by SMART when it reaches "30% good". It had been as low as "60% good" once, but has magically recovered since. Note that the interpreted values are calculated by the drive's SMART logic internally and the exact calculation may or may not be published by the manufacturer and typically cannot be tweaked by the user.

Personally, I consider a drive containing error log entries as "failing" and urge for a replacement as soon as they occur. But all in all, SMART data has turned out to be a rather weak indicator for failure prediction, as a research paper published by Google uncovered.