Импорт таблиц в Mathematica из Web — проблема с пустой ячейкой

#import #wolfram-mathematica

#импорт #wolfram-mathematica

Вопрос:

Я использую:
data=Import["http://weburl/","Data"]
импортировать данные с одного сайта. На этой странице есть таблицы. Это создает вложенные списки, и вы можете легко получить данные в виде таблицы. Например:
Grid[data[[1]]]
дало бы что-то вроде этого:

 Player Age Shots Goals
  P1    24    10    2 
  P2    22     5    0
  P3    28    11    1
  ...
  

Итак, вот в чем проблема. Если одна ячейка в html-таблице пуста, например запись для «Age», то в html это будет выглядеть следующим образом: <td></td> . Mathematica вообще не включает take it в список, даже как, например, значение «Null». Вместо этого эта строка была бы просто представлена списком длиной 3, а данные были бы перемещены на один столбец, так что вы получили бы «Снимки» вместо «Возраста» и «Цели» вместо «Снимков», а «Цели» были бы пустыми.
Например, «P4», возраст которого неизвестен (пустая ячейка в html-таблице), который нанес 10 ударов и забил 0 голов, будет импортирован как список длиной 3, а не 4, и перемещен на единицу:

 Player Age Shots Goals
  P1    24    10    2 
  P2    22     5    0
  P3    10     0  
  ...
  

Это создает сложную проблему, потому что если у вас есть несколько пустых полей, то вы не можете определить из списка, к какому столбцу оно относится. Есть ли способ поместить «Null» в пустую ячейку в таблицах html при импорте в Mathematica? Например, элемент P4 в списке будет выглядеть следующим образом:
data[[1,5]]
{"P4","Null",10,0}
вместо:
{"P4",10,0}

Комментарии:

1. Словами велисариуса: Позвольте мне поприветствовать вас в StackOverflow и напомнить три вещи, которые мы обычно делаем здесь: 1) Когда вы получаете помощь, постарайтесь также оказать ее, отвечая на вопросы в вашей области знаний 2) Прочитайте часто задаваемые вопросы 3) Когда вы видите хорошие вопросы и ответы, проголосуйте за них, используя серые треугольники, поскольку доверие к системе основано на репутации, которую пользователи получают, делясь своими знаниями. Также не забудьте принять ответ, который лучше решает вашу проблему, если таковой имеется, нажав на галочку

2. Было бы полезно предоставить пример страницы для тестирования.

3. В итоге я использовал Import[«url», «FullData»] //InputForm, что дало мне желаемый результат. Но я определенно буду иметь в виду все ваши предложения для моей будущей работы. //InputForm была очень полезной командой. Спасибо вам всем!

Ответ №1:

Как указывает lumeng, вы можете использовать FullData для правильного заполнения элемента HTML-таблицы. Вот более простая иллюстрация этого.

 in = ImportString["<<html><table>
   <tr>
   <td>(1,1)</td>
   <td>(1,2)</td>
   <td>(1,3)</td>
   </tr>
   <tr>
   <td>(2,1)</td>
   <td></td>
   <td>(2,3)</td>
   </tr>
   </table></html>>",
   {"HTML", "FullData"}];
Grid[in[[1, 1]]]
  

Если вы хотите более полный контроль над выводом, я бы посоветовал вам Import представить страницу в формате XML. Вот пример.

 in = ImportString["<<html><table>
    <tr>
    <td>(1,1)</td>
    <td>(1,2)</td>
    <td>(1,3)</td>
    </tr>
    <tr>
    <td>(2,1)</td>
    <td></td>
    <td>(2,3)</td>
    </tr>
    </table></html>>", "XML"];
Column[Last /@ Cases[in,
   XMLElement["td", ___], Infinity]]
  

Вам нужно будет немного ознакомиться с XML в целом и версией Mathematica, а именно XMLObject . С этим приятно работать, как только вы освоитесь с этим.

Комментарии:

1. Каково значение "<...>" синтаксиса, который вы используете в строке примера?

2. @WReach. Эта форма правильно распознает символы новой строки, поэтому ее обычно используют при вводе блока текста.

3. Хорошо, {«Html», «FullData»} выполняет свою работу, я получаю всю информацию. Но мне придется применить другой подход, «FullData» полностью разрушает хорошо структурированные данные, которые я получаю с помощью «Data». Поскольку на моей странице есть огромное количество таблиц, которые меняются, эти вложенные списки представляют собой слишком большой беспорядок. Поэтому я, вероятно, попытаюсь заменить <td></td>s и аналогичные пустые ячейки на <td>Null</td>, а затем импортировать с помощью «Data».

4. В итоге я использовал Import[«url», «FullData»] //InputForm, что дало мне желаемый результат. Но я определенно буду иметь в виду все ваши предложения для моей будущей работы. //InputForm была очень полезной командой. Спасибо вам всем!

Ответ №2:

 In[13]:= htmlcode = "<html><table border="1">
<tr>
<td>row 1, cell 1</td>
<td>row 1, cell 2</td>
<td>row 1, cell 3</td>
</tr>
<tr>
<td>row 2, cell 1</td>
<td></td>
<td>row 2, cell 3</td>
</tr>
</table><html>";

In[14]:= file = ToFileName[{$TemporaryDirectory}, "tmp.html"]
Out[14]= "/tmp/tmp.html"


In[15]:= OpenWrite[file]
WriteString[file,htmlcode]
Close[file]
FilePrint[file]
Out[15]= OutputStream[/tmp/tmp.html,18]
Out[17]= /tmp/tmp.html
During evaluation of In[15]:=
<html><table border="1">
<tr>
<td>row 1, cell 1</td>
<td>row 1, cell 2</td>
<td>row 1, cell 3</td>
</tr>
<tr>
<td>row 2, cell 1</td>
<td></td>
<td>row 2, cell 3</td>
</tr>
</table><html>
In[23]:= Import[file,"Elements"]//InputForm
Out[23]//InputForm=
{"Data", "FullData", "Hyperlinks", "ImageLinks", "Images", "Plaintext", "Source", "Title", "XMLObject"}
In[22]:= Import[file,"FullData"]//InputForm
Out[22]//InputForm=
{{{{"row 1, cell 1", "row 1, cell 2", "row 1, cell 3"}, {"row 2, cell 1", "", "row 2, cell 3"}}}, {}}
  

Комментарии:

1. разработчик, чего ты пытаешься здесь достичь? Пожалуйста, объясните, что делает код.

2. @rcollyer, как я вижу, он записывает пример HTML-таблицы в файл, который он считывает обратно Import . Опция «FullData» используется для заполнения пробелов. Запись файла могла бы быть выполнена несколько проще с помощью ‘Put’ или ‘Export’. Даже нет необходимости использовать файл для этой демонстрации, поскольку есть также ImportString который обрабатывает строку как файл для импорта.

3. @Sjoerd, я знаю, что это делает, но я пытаюсь поощрять подход типа «больше объяснений, меньше кода». На мой взгляд, большой блок кода по сути бесполезен без какого-либо сопровождающего объяснения. В своем текущем виде он служит для ответа на вопрос, но только в самом широком смысле, поскольку он не дает никаких указаний относительно контекста или мотивации решения. Это похоже на чтение математического доказательства без какого-либо сопроводительного текста; оно может быть правильным, но его едва ли можно считать читаемым.

4. Как я уже говорил в посте Марка Макклурса, я попытаюсь присвоить значение «Null» пустым ячейкам, поскольку FullData разрушает элегантность «Данных». Итак, я импортирую html-код, помещаю Null в пустые ячейки и их ImportString[data, «Данные»] и должен получить легко читаемую таблицу.

Ответ №3:

Используя пример Computist, вы также могли бы сделать:

 htmlcode = "<html><table border="1">
  <tr>
  <td>row 1, cell 1</td>
  <td>row 1, cell 2</td>
  <td>row 1, cell 3</td>
  </tr>
  <tr>
  <td>row 2, cell 1</td>
  <td></td>
  <td>row 2, cell 3</td>
  </tr>
  </table><html>";

StringReplace[htmlcode, "<td></td>" -> "<td>###</td>"];

ImportString[%, "Data"] /. "###" -> Null